Fix issues with file creation
Not all of the frames were even fetched from Kvazaar after encoding! This commit fixes this issue. Also the Kvazaar structures were not freed, now they are.
This commit is contained in:
parent
ee19be93dd
commit
c93b988bed
16
create.pl
16
create.pl
|
@ -18,16 +18,16 @@ sub print_help {
|
|||
}
|
||||
|
||||
GetOptions(
|
||||
"input|i=s" => \(my $filename = ""),
|
||||
"resolution|res=s" => \(my $resolution = "3840x2160"),
|
||||
"quantization|qp=i" => \(my $qp = 32),
|
||||
"framerate|fps=i" => \(my $fps = 30),
|
||||
"intra-period|intra=i" => \(my $period = 64),
|
||||
"preset|pre=s" => \(my $preset = "ultrafast"),
|
||||
"help" => \(my $help = 0)
|
||||
"input|file|filename|i=s" => \(my $filename = ""),
|
||||
"resolution|res=s" => \(my $resolution = "3840x2160"),
|
||||
"quantization|qp=i" => \(my $qp = 32),
|
||||
"framerate|fps=i" => \(my $fps = 30),
|
||||
"intra-period|intra=i" => \(my $period = 64),
|
||||
"preset|pre=s" => \(my $preset = "ultrafast"),
|
||||
"help" => \(my $help = 0)
|
||||
) or die "failed to parse command line!\n";
|
||||
|
||||
print_help() if $help or !$filename or !$resolution;
|
||||
print_help() if $help or !$filename;
|
||||
|
||||
# check that parameters make sense
|
||||
die "" if $help;
|
||||
|
|
|
@ -11,7 +11,10 @@
|
|||
int kvazaar_encode(const std::string& input, const std::string& output,
|
||||
int width, int height, int qp, int fps, int period, std::string& preset);
|
||||
|
||||
void cleanup(FILE* inputFile, FILE* outputFile);
|
||||
bool encode_frame(kvz_picture* input, int& rvalue, FILE* outputFile, const kvz_api* api, kvz_encoder* enc);
|
||||
|
||||
void cleanup_files(FILE* inputFile, FILE* outputFile);
|
||||
void cleanup_kvazaar(kvz_picture* input, const kvz_api* api, kvz_encoder* enc, kvz_config* config);
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
@ -67,12 +70,12 @@ int kvazaar_encode(const std::string& input, const std::string& output,
|
|||
if (inputFile == NULL || outputFile == NULL)
|
||||
{
|
||||
std::cerr << "Failed to open input or output file!" << std::endl;
|
||||
cleanup(inputFile, outputFile);
|
||||
cleanup_files(inputFile, outputFile);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
kvz_encoder* enc = NULL;
|
||||
const kvz_api* const api = kvz_api_get(8);
|
||||
const kvz_api* api = kvz_api_get(8);
|
||||
kvz_config* config = api->config_alloc();
|
||||
api->config_init(config);
|
||||
api->config_parse(config, "preset", preset.c_str());
|
||||
|
@ -85,101 +88,51 @@ int kvazaar_encode(const std::string& input, const std::string& output,
|
|||
config->framerate_denom = 1;
|
||||
|
||||
enc = api->encoder_open(config);
|
||||
if (!enc) {
|
||||
kvz_picture* img_in = api->picture_alloc(width, height);
|
||||
|
||||
if (!enc || !img_in) {
|
||||
std::cerr << "Failed to open kvazaar encoder!" << std::endl;
|
||||
cleanup(inputFile, outputFile);
|
||||
cleanup_files(inputFile, outputFile);
|
||||
cleanup_kvazaar(img_in, api, enc, config);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
kvz_picture* img_in[16];
|
||||
for (uint32_t i = 0; i < 16; ++i) {
|
||||
img_in[i] = api->picture_alloc_csp(KVZ_CSP_420, width, height);
|
||||
}
|
||||
|
||||
uint8_t inputCounter = 0;
|
||||
uint8_t outputCounter = 0;
|
||||
int frame_count = 1;
|
||||
bool done = false;
|
||||
/* int r = 0; */
|
||||
bool input_has_been_read = false;
|
||||
|
||||
std::cout << "Start creating the HEVC benchmark file from " << input << std::endl;
|
||||
while (!input_has_been_read) {
|
||||
|
||||
while (!done) {
|
||||
kvz_data_chunk* chunks_out = NULL;
|
||||
kvz_picture* img_rec = NULL;
|
||||
kvz_picture* img_src = NULL;
|
||||
uint32_t len_out = 0;
|
||||
kvz_frame_info info_out;
|
||||
if (fread(img_in->y, width * height, 1, inputFile) == 0 ||
|
||||
fread(img_in->u, width * height >> 2, 1, inputFile) == 0 ||
|
||||
fread(img_in->v, width * height >> 2, 1, inputFile) == 0) {
|
||||
std::cout << "Cannot read more values from file" << std::endl;
|
||||
input_has_been_read = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::cout << "Start encoding frame " << frame_count << std::endl;
|
||||
++frame_count;
|
||||
|
||||
if (fread(img_in[inputCounter]->y, width * height, 1, inputFile) == 0) {
|
||||
std::cout << "Cannot read y values size " << (width * height) << std::endl;
|
||||
done = true;
|
||||
continue;
|
||||
}
|
||||
if (fread(img_in[inputCounter]->u, width * height >> 2, 1, inputFile) == 0) {
|
||||
std::cout << "Cannot read u values size " << (width * height >> 2) << std::endl;
|
||||
done = true;
|
||||
continue;
|
||||
}
|
||||
if (fread(img_in[inputCounter]->v, width * height >> 2, 1, inputFile) == 0) {
|
||||
std::cout << "Cannot read v values size " << (width * height >> 2) << std::endl;
|
||||
done = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!api->encoder_encode(enc,
|
||||
img_in[inputCounter],
|
||||
&chunks_out, &len_out, &img_rec, &img_src, &info_out))
|
||||
// feed input to kvazaar and write output to file
|
||||
int rvalue = EXIT_FAILURE;
|
||||
if (!encode_frame(img_in, rvalue, outputFile, api, enc))
|
||||
{
|
||||
fprintf(stderr, "Failed to encode image.\n");
|
||||
for (uint32_t i = 0; i < 16; i++) {
|
||||
api->picture_free(img_in[i]);
|
||||
}
|
||||
cleanup(inputFile, outputFile);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
inputCounter = (inputCounter + 1) % 16;
|
||||
|
||||
|
||||
if (chunks_out == NULL && img_in == NULL) {
|
||||
// We are done since there is no more input and output left.
|
||||
cleanup(inputFile, outputFile);
|
||||
std::cout << "No more input or output. Finished creating the HEVC benchmark file to " << output << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (chunks_out != NULL) {
|
||||
uint64_t written = 0;
|
||||
|
||||
// Write data into the output file.
|
||||
for (kvz_data_chunk* chunk = chunks_out; chunk != NULL; chunk = chunk->next) {
|
||||
written += chunk->len;
|
||||
}
|
||||
|
||||
fprintf(stderr, "write chunk size: %lu\n", written);
|
||||
fwrite(&written, sizeof(uint64_t), 1, outputFile);
|
||||
for (kvz_data_chunk* chunk = chunks_out; chunk != NULL; chunk = chunk->next) {
|
||||
fwrite(chunk->data, chunk->len, 1, outputFile);
|
||||
}
|
||||
|
||||
outputCounter = (outputCounter + 1) % 16;
|
||||
|
||||
/* if (++r > 5) */
|
||||
/* goto cleanup; */
|
||||
cleanup_files(inputFile, outputFile);
|
||||
cleanup_kvazaar(img_in, api, enc, config);
|
||||
return rvalue;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Finished creating the HEVC benchmark file to " << output << std::endl;
|
||||
// write the rest of the frames that are being encoded to file
|
||||
int rvalue = EXIT_FAILURE;
|
||||
while (encode_frame(nullptr, rvalue, outputFile, api, enc));
|
||||
|
||||
cleanup(inputFile, outputFile);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
cleanup_files(inputFile, outputFile);
|
||||
cleanup_kvazaar(img_in, api, enc, config);
|
||||
return rvalue;
|
||||
}
|
||||
|
||||
void cleanup(FILE* inputFile, FILE* outputFile)
|
||||
void cleanup_files(FILE* inputFile, FILE* outputFile)
|
||||
{
|
||||
if (inputFile)
|
||||
{
|
||||
|
@ -190,4 +143,73 @@ void cleanup(FILE* inputFile, FILE* outputFile)
|
|||
{
|
||||
fclose(outputFile);
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup_kvazaar(kvz_picture* input, const kvz_api* api, kvz_encoder* enc, kvz_config* config)
|
||||
{
|
||||
if (api)
|
||||
{
|
||||
if (enc)
|
||||
{
|
||||
api->encoder_close(enc);
|
||||
}
|
||||
|
||||
if (config)
|
||||
{
|
||||
api->config_destroy(config);
|
||||
}
|
||||
|
||||
if (input)
|
||||
{
|
||||
api->picture_free(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool encode_frame(kvz_picture* input, int& rvalue, FILE* outputFile, const kvz_api* api, kvz_encoder* enc)
|
||||
{
|
||||
kvz_picture* img_rec = nullptr;
|
||||
kvz_picture* img_src = nullptr;
|
||||
uint32_t len_out = 0;
|
||||
kvz_frame_info info_out;
|
||||
kvz_data_chunk* chunks_out = nullptr;
|
||||
|
||||
if (!api->encoder_encode(enc, input, &chunks_out, &len_out, &img_rec, &img_src, &info_out))
|
||||
{
|
||||
fprintf(stderr, "Failed to encode image.\n");
|
||||
for (uint32_t i = 0; i < 16; i++) {
|
||||
api->picture_free(input);
|
||||
}
|
||||
rvalue = EXIT_FAILURE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (chunks_out == nullptr && input == nullptr) {
|
||||
// We are done since there is no more input or output left.
|
||||
rvalue = EXIT_SUCCESS;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (chunks_out != NULL) {
|
||||
uint64_t written = 0;
|
||||
|
||||
// Calculate the total size of the chunks
|
||||
for (kvz_data_chunk* chunk = chunks_out; chunk != nullptr; chunk = chunk->next) {
|
||||
written += chunk->len;
|
||||
}
|
||||
|
||||
std::cout << "Write the size of the chunk: " << written << std::endl;
|
||||
|
||||
// write the size of the chunks into the file also. This makes the files unusable for normal
|
||||
// viewing. It would be better to write the sizes to a separate file
|
||||
fwrite(&written, sizeof(uint64_t), 1, outputFile);
|
||||
|
||||
// write the chunks into the file
|
||||
for (kvz_data_chunk* chunk = chunks_out; chunk != nullptr; chunk = chunk->next) {
|
||||
fwrite(chunk->data, chunk->len, 1, outputFile);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
Loading…
Reference in New Issue