Commit 17dd3f6d for libheif
commit 17dd3f6d7e09146b42c91534f6d19e79cfdf911a
Author: Dirk Farin <dirk.farin@gmail.com>
Date: Fri Dec 19 10:08:25 2025 +0100
[BSD3] pass sequence framerate through to encoders
diff --git a/libheif/api/libheif/heif_plugin.h b/libheif/api/libheif/heif_plugin.h
index c8af91e1..a45d2343 100644
--- a/libheif/api/libheif/heif_plugin.h
+++ b/libheif/api/libheif/heif_plugin.h
@@ -286,6 +286,7 @@ typedef struct heif_encoder_plugin
heif_error (* start_sequence_encoding)(void* encoder, const heif_image* image,
enum heif_image_input_class image_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options);
// TODO: is heif_sequence_encoding_options a good choice here?
diff --git a/libheif/codecs/avc_enc.cc b/libheif/codecs/avc_enc.cc
index 9c65405d..b985af76 100644
--- a/libheif/codecs/avc_enc.cc
+++ b/libheif/codecs/avc_enc.cc
@@ -121,13 +121,16 @@ Error Encoder_AVC::encode_sequence_frame(const std::shared_ptr<HeifPixelImage>&
heif_encoder* encoder,
const heif_sequence_encoding_options& options,
heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
uintptr_t frame_number)
{
heif_image c_api_image;
c_api_image.image = image;
if (!m_encoder_active) {
- heif_error err = encoder->plugin->start_sequence_encoding(encoder->encoder, &c_api_image, input_class,
+ heif_error err = encoder->plugin->start_sequence_encoding(encoder->encoder, &c_api_image,
+ input_class,
+ framerate_num, framerate_denom,
&options);
if (err.code) {
return {
diff --git a/libheif/codecs/avc_enc.h b/libheif/codecs/avc_enc.h
index 77ff75ff..c63d406d 100644
--- a/libheif/codecs/avc_enc.h
+++ b/libheif/codecs/avc_enc.h
@@ -46,6 +46,7 @@ public:
heif_encoder* encoder,
const heif_sequence_encoding_options& options,
heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
uintptr_t frame_number) override;
Error encode_sequence_flush(heif_encoder* encoder) override;
diff --git a/libheif/codecs/avif_enc.cc b/libheif/codecs/avif_enc.cc
index 0160a76b..b47664d0 100644
--- a/libheif/codecs/avif_enc.cc
+++ b/libheif/codecs/avif_enc.cc
@@ -86,6 +86,7 @@ Error Encoder_AVIF::encode_sequence_frame(const std::shared_ptr<HeifPixelImage>&
heif_encoder* encoder,
const heif_sequence_encoding_options& options,
heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
uintptr_t frame_number)
{
// Box_av1C::configuration config;
@@ -101,6 +102,7 @@ Error Encoder_AVIF::encode_sequence_frame(const std::shared_ptr<HeifPixelImage>&
heif_error err = encoder->plugin->start_sequence_encoding(encoder->encoder,
&c_api_image,
input_class,
+ framerate_num, framerate_denom,
&options);
if (err.code) {
return {
diff --git a/libheif/codecs/avif_enc.h b/libheif/codecs/avif_enc.h
index 4a7eafe7..f704a4f8 100644
--- a/libheif/codecs/avif_enc.h
+++ b/libheif/codecs/avif_enc.h
@@ -48,6 +48,7 @@ public:
heif_encoder* encoder,
const heif_sequence_encoding_options& options,
heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
uintptr_t frame_number) override;
Error encode_sequence_flush(heif_encoder* encoder) override;
diff --git a/libheif/codecs/encoder.h b/libheif/codecs/encoder.h
index 349d2b36..ba51d0e0 100644
--- a/libheif/codecs/encoder.h
+++ b/libheif/codecs/encoder.h
@@ -79,6 +79,7 @@ public:
heif_encoder* encoder,
const heif_sequence_encoding_options& options,
heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
uintptr_t frame_number) { return {}; }
virtual Error encode_sequence_flush(heif_encoder* encoder) { return {}; }
diff --git a/libheif/codecs/hevc_enc.cc b/libheif/codecs/hevc_enc.cc
index 90d5e550..ada5b89d 100644
--- a/libheif/codecs/hevc_enc.cc
+++ b/libheif/codecs/hevc_enc.cc
@@ -116,13 +116,16 @@ Error Encoder_HEVC::encode_sequence_frame(const std::shared_ptr<HeifPixelImage>&
heif_encoder* encoder,
const heif_sequence_encoding_options& options,
heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
uintptr_t frame_number)
{
heif_image c_api_image;
c_api_image.image = image;
if (!m_encoder_active) {
- heif_error err = encoder->plugin->start_sequence_encoding(encoder->encoder, &c_api_image, input_class,
+ heif_error err = encoder->plugin->start_sequence_encoding(encoder->encoder, &c_api_image,
+ input_class,
+ framerate_num, framerate_denom,
&options);
if (err.code) {
return {
diff --git a/libheif/codecs/hevc_enc.h b/libheif/codecs/hevc_enc.h
index 79c38c09..20c7cfaa 100644
--- a/libheif/codecs/hevc_enc.h
+++ b/libheif/codecs/hevc_enc.h
@@ -46,6 +46,7 @@ public:
heif_encoder* encoder,
const heif_sequence_encoding_options& options,
heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
uintptr_t frame_number) override;
Error encode_sequence_flush(heif_encoder* encoder) override;
diff --git a/libheif/codecs/jpeg2000_enc.h b/libheif/codecs/jpeg2000_enc.h
index dfff2623..a535bab7 100644
--- a/libheif/codecs/jpeg2000_enc.h
+++ b/libheif/codecs/jpeg2000_enc.h
@@ -48,6 +48,7 @@ public:
heif_encoder* encoder,
const heif_sequence_encoding_options& options,
heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
uintptr_t frame_number) override
{
heif_encoding_options dummy_options{};
diff --git a/libheif/codecs/jpeg_enc.h b/libheif/codecs/jpeg_enc.h
index 62c1cdc6..ed8b8cdd 100644
--- a/libheif/codecs/jpeg_enc.h
+++ b/libheif/codecs/jpeg_enc.h
@@ -51,6 +51,7 @@ public:
heif_encoder* encoder,
const heif_sequence_encoding_options& options,
heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
uintptr_t frame_number) override
{
heif_encoding_options dummy_options{};
diff --git a/libheif/codecs/uncompressed/unc_enc.h b/libheif/codecs/uncompressed/unc_enc.h
index c61285a3..01d7eeeb 100644
--- a/libheif/codecs/uncompressed/unc_enc.h
+++ b/libheif/codecs/uncompressed/unc_enc.h
@@ -48,6 +48,7 @@ public:
heif_encoder* encoder,
const heif_sequence_encoding_options& options,
heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
uintptr_t frame_number) override
{
heif_encoding_options dummy_options{};
diff --git a/libheif/codecs/vvc_enc.cc b/libheif/codecs/vvc_enc.cc
index 948a94ed..db21faf1 100644
--- a/libheif/codecs/vvc_enc.cc
+++ b/libheif/codecs/vvc_enc.cc
@@ -120,6 +120,7 @@ Error Encoder_VVC::encode_sequence_frame(const std::shared_ptr<HeifPixelImage>&
heif_encoder* encoder,
const heif_sequence_encoding_options& options,
heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
uintptr_t frame_number)
{
heif_image c_api_image;
@@ -127,6 +128,7 @@ Error Encoder_VVC::encode_sequence_frame(const std::shared_ptr<HeifPixelImage>&
if (!m_encoder_active) {
heif_error err = encoder->plugin->start_sequence_encoding(encoder->encoder, &c_api_image, input_class,
+ framerate_num, framerate_denom,
&options);
if (err.code) {
return {
diff --git a/libheif/codecs/vvc_enc.h b/libheif/codecs/vvc_enc.h
index 324620a2..40b3b24f 100644
--- a/libheif/codecs/vvc_enc.h
+++ b/libheif/codecs/vvc_enc.h
@@ -49,6 +49,7 @@ public:
heif_encoder* encoder,
const heif_sequence_encoding_options& options,
heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
uintptr_t frame_number) override;
Error encode_sequence_flush(heif_encoder* encoder) override;
diff --git a/libheif/plugins/encoder_aom.cc b/libheif/plugins/encoder_aom.cc
index 0d7db404..6e58a8aa 100644
--- a/libheif/plugins/encoder_aom.cc
+++ b/libheif/plugins/encoder_aom.cc
@@ -859,6 +859,7 @@ chroma_info get_chroma_info(heif_chroma chroma,
static heif_error aom_start_sequence_encoding_intern(void* encoder_raw, const heif_image* image,
enum heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options,
bool image_sequence)
{
@@ -1014,6 +1015,9 @@ static heif_error aom_start_sequence_encoding_intern(void* encoder_raw, const he
cfg.monochrome = 1;
}
+ cfg.g_timebase.num = static_cast<int>(framerate_num);
+ cfg.g_timebase.den = static_cast<int>(framerate_denom);
+
// --- initialize codec
aom_codec_flags_t encoder_flags = 0;
@@ -1115,9 +1119,10 @@ static heif_error aom_start_sequence_encoding_intern(void* encoder_raw, const he
static heif_error aom_start_sequence_encoding(void* encoder_raw, const heif_image* image,
enum heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options)
{
- return aom_start_sequence_encoding_intern(encoder_raw, image, input_class, options,
+ return aom_start_sequence_encoding_intern(encoder_raw, image, input_class, framerate_num, framerate_denom, options,
true);
}
@@ -1309,7 +1314,7 @@ static heif_error aom_encode_image(void* encoder_raw, const heif_image* image,
heif_image_input_class input_class)
{
heif_error err;
- err = aom_start_sequence_encoding_intern(encoder_raw, image, input_class, nullptr, false);
+ err = aom_start_sequence_encoding_intern(encoder_raw, image, input_class, 1,25, nullptr, false);
if (err.code) {
return err;
}
diff --git a/libheif/plugins/encoder_jpeg.cc b/libheif/plugins/encoder_jpeg.cc
index 633c12ae..7dde0e43 100644
--- a/libheif/plugins/encoder_jpeg.cc
+++ b/libheif/plugins/encoder_jpeg.cc
@@ -446,6 +446,7 @@ heif_error jpeg_get_compressed_data(void* encoder_raw, uint8_t** data, int* size
heif_error jpeg_start_sequence_encoding(void* encoder, const heif_image* image,
enum heif_image_input_class image_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options)
{
return heif_error_ok;
diff --git a/libheif/plugins/encoder_kvazaar.cc b/libheif/plugins/encoder_kvazaar.cc
index 1150aff1..3f5fae0e 100644
--- a/libheif/plugins/encoder_kvazaar.cc
+++ b/libheif/plugins/encoder_kvazaar.cc
@@ -453,6 +453,7 @@ std::unique_ptr<T, D> make_guard(T* ptr, D&& deleter) {
static heif_error kvazaar_start_sequence_encoding_intern(void* encoder_raw, const heif_image* image,
enum heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options,
bool image_sequence)
{
@@ -503,6 +504,9 @@ static heif_error kvazaar_start_sequence_encoding_intern(void* encoder_raw, cons
uint32_t encoded_width, encoded_height;
kvazaar_query_encoded_size(encoder_raw, input_width, input_height, &encoded_width, &encoded_height);
+ config->framerate_num = framerate_num;
+ config->framerate_denom = framerate_denom;
+
if (isGreyscale) {
config->input_format = KVZ_FORMAT_P400;
}
@@ -558,8 +562,6 @@ static heif_error kvazaar_start_sequence_encoding_intern(void* encoder_raw, cons
// TODO
/*
config->target_bitrate = options->sequence_bitrate;
- config->framerate_num = options->framerate_num;
- config->framerate_den = options->framerate_den;
*/
if (options->keyframe_distance_max) {
@@ -893,9 +895,10 @@ static heif_error kvazaar_get_compressed_data2(void* encoder_raw, uint8_t** data
static heif_error kvazaar_start_sequence_encoding(void* encoder_raw, const heif_image* image,
enum heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options)
{
- return kvazaar_start_sequence_encoding_intern(encoder_raw, image, input_class, options, true);
+ return kvazaar_start_sequence_encoding_intern(encoder_raw, image, input_class, framerate_num, framerate_denom, options, true);
}
@@ -903,7 +906,7 @@ static heif_error kvazaar_encode_image(void* encoder_raw, const heif_image* imag
heif_image_input_class input_class)
{
heif_error err;
- err = kvazaar_start_sequence_encoding_intern(encoder_raw, image, input_class, nullptr, false);
+ err = kvazaar_start_sequence_encoding_intern(encoder_raw, image, input_class, 1,25, nullptr, false);
if (err.code) {
return err;
}
diff --git a/libheif/plugins/encoder_openjpeg.cc b/libheif/plugins/encoder_openjpeg.cc
index 4282ca77..3bbbe0b2 100644
--- a/libheif/plugins/encoder_openjpeg.cc
+++ b/libheif/plugins/encoder_openjpeg.cc
@@ -598,6 +598,7 @@ void opj_query_encoded_size(void* encoder, uint32_t input_width, uint32_t input_
heif_error opj_start_sequence_encoding(void* encoder, const heif_image* image,
enum heif_image_input_class image_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options)
{
return heif_error_ok;
diff --git a/libheif/plugins/encoder_openjph.cc b/libheif/plugins/encoder_openjph.cc
index 07c1d4e0..284e7176 100644
--- a/libheif/plugins/encoder_openjph.cc
+++ b/libheif/plugins/encoder_openjph.cc
@@ -853,6 +853,7 @@ const char* ojph_plugin_name()
heif_error ojph_start_sequence_encoding(void* encoder, const heif_image* image,
enum heif_image_input_class image_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options)
{
return heif_error_ok;
diff --git a/libheif/plugins/encoder_rav1e.cc b/libheif/plugins/encoder_rav1e.cc
index bfe1f529..641618b7 100644
--- a/libheif/plugins/encoder_rav1e.cc
+++ b/libheif/plugins/encoder_rav1e.cc
@@ -503,6 +503,7 @@ void rav1e_query_input_colorspace2(void* encoder_raw, heif_colorspace* colorspac
heif_error rav1e_start_sequence_encoding_intern(void* encoder_raw, const heif_image* image,
enum heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options,
bool image_sequence)
{
@@ -562,6 +563,8 @@ heif_error rav1e_start_sequence_encoding_intern(void* encoder_raw, const heif_im
return heif_error_codec_library_error;
}
+ rav1e_config_set_time_base(rav1eConfig.get(), RaRational{framerate_num, framerate_denom});
+
if (!image_sequence) {
if (rav1e_config_parse(rav1eConfig.get(), "still_picture", "true") == -1) {
return heif_error_codec_library_error;
@@ -654,9 +657,11 @@ heif_error rav1e_start_sequence_encoding_intern(void* encoder_raw, const heif_im
heif_error rav1e_start_sequence_encoding(void* encoder_raw, const heif_image* image,
enum heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options)
{
- return rav1e_start_sequence_encoding_intern(encoder_raw, image, input_class, options, true);
+ return rav1e_start_sequence_encoding_intern(encoder_raw, image, input_class,
+ framerate_num, framerate_denom, options, true);
}
@@ -807,7 +812,7 @@ heif_error rav1e_encode_image(void* encoder_raw, const heif_image* image,
heif_image_input_class input_class)
{
heif_error err;
- err = rav1e_start_sequence_encoding_intern(encoder_raw, image, input_class, nullptr, false);
+ err = rav1e_start_sequence_encoding_intern(encoder_raw, image, input_class, 1,25, nullptr, false);
if (err.code) {
return err;
}
diff --git a/libheif/plugins/encoder_svt.cc b/libheif/plugins/encoder_svt.cc
index 83fa4bc3..03d87ca1 100644
--- a/libheif/plugins/encoder_svt.cc
+++ b/libheif/plugins/encoder_svt.cc
@@ -690,6 +690,7 @@ void svt_query_encoded_size(void* encoder_raw, uint32_t input_width, uint32_t in
static heif_error svt_start_sequence_encoding_intern(void* encoder_raw, const heif_image* image,
enum heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options,
bool image_sequence)
{
@@ -869,6 +870,9 @@ static heif_error svt_start_sequence_encoding_intern(void* encoder_raw, const he
svt_config.profile = HIGH_PROFILE;
}
+ svt_config.frame_rate_numerator = framerate_num;
+ svt_config.frame_rate_denominator = framerate_denom;
+
res = svt_av1_enc_set_parameter(svt_encoder, &svt_config);
if (res == EB_ErrorBadParameter) {
return heif_error_codec_library_error;
@@ -1165,9 +1169,11 @@ heif_error svt_get_compressed_data(void* encoder_raw, uint8_t** data, int* size,
static heif_error svt_start_sequence_encoding(void* encoder_raw, const heif_image* image,
enum heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options)
{
- return svt_start_sequence_encoding_intern(encoder_raw, image, input_class, options, true);
+ return svt_start_sequence_encoding_intern(encoder_raw, image, input_class,
+ framerate_num, framerate_denom, options, true);
}
@@ -1175,7 +1181,7 @@ heif_error svt_encode_image(void* encoder_raw, const heif_image* image,
heif_image_input_class input_class)
{
heif_error err;
- err = svt_start_sequence_encoding_intern(encoder_raw, image, input_class, nullptr, false);
+ err = svt_start_sequence_encoding_intern(encoder_raw, image, input_class, 1,25, nullptr, false);
if (err.code) {
return err;
}
diff --git a/libheif/plugins/encoder_uncompressed.cc b/libheif/plugins/encoder_uncompressed.cc
index 29091c86..05ab2391 100644
--- a/libheif/plugins/encoder_uncompressed.cc
+++ b/libheif/plugins/encoder_uncompressed.cc
@@ -292,6 +292,7 @@ heif_error uncompressed_get_compressed_data(void* encoder_raw, uint8_t** data, i
heif_error uncompressed_start_sequence_encoding(void* encoder, const heif_image* image,
enum heif_image_input_class image_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options)
{
return heif_error_ok;
diff --git a/libheif/plugins/encoder_uvg266.cc b/libheif/plugins/encoder_uvg266.cc
index 4bb4976e..90ff2d2e 100644
--- a/libheif/plugins/encoder_uvg266.cc
+++ b/libheif/plugins/encoder_uvg266.cc
@@ -459,6 +459,7 @@ static void copy_plane(uvg_pixel* out_p, size_t out_stride, const uint8_t* in_p,
static heif_error uvg266_start_sequence_encoding_intern(void* encoder_raw, const heif_image* image,
heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options,
bool image_sequence)
{
@@ -592,6 +593,9 @@ static heif_error uvg266_start_sequence_encoding_intern(void* encoder_raw, const
}
}
+ config->framerate_num = framerate_num;
+ config->framerate_denom = framerate_denom;
+
uint32_t encoded_width, encoded_height;
uvg266_query_encoded_size(encoder_raw, input_width, input_height, &encoded_width, &encoded_height);
@@ -789,9 +793,11 @@ static heif_error uvg266_get_compressed_data_intern(void* encoder_raw, uint8_t**
static heif_error uvg266_start_sequence_encoding(void* encoder_raw, const heif_image* image,
heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options)
{
- return uvg266_start_sequence_encoding_intern(encoder_raw, image, input_class, options, true);
+ return uvg266_start_sequence_encoding_intern(encoder_raw, image, input_class,
+ framerate_num, framerate_denom, options, true);
}
static heif_error uvg266_end_sequence_encoding(void* encoder_raw)
@@ -851,7 +857,7 @@ static heif_error uvg266_encode_image(void* encoder_raw, const heif_image* image
heif_image_input_class input_class)
{
heif_error err;
- err = uvg266_start_sequence_encoding_intern(encoder_raw, image, input_class, nullptr, false);
+ err = uvg266_start_sequence_encoding_intern(encoder_raw, image, input_class, 1,25, nullptr, false);
if (err.code) {
return err;
}
diff --git a/libheif/plugins/encoder_vvenc.cc b/libheif/plugins/encoder_vvenc.cc
index 3ac7d3c4..778b68bf 100644
--- a/libheif/plugins/encoder_vvenc.cc
+++ b/libheif/plugins/encoder_vvenc.cc
@@ -428,6 +428,7 @@ static void copy_plane(int16_t* dst_p, size_t dst_stride, const uint8_t* in_p, s
static heif_error vvenc_start_sequence_encoding_intern(void* encoder_raw, const heif_image* image,
enum heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options,
bool image_sequence)
{
@@ -455,8 +456,9 @@ static heif_error vvenc_start_sequence_encoding_intern(void* encoder_raw, const
int encoder_quality = 63 - encoder->quality*63/100;
int ret = vvenc_init_default(¶ms,
- encoder->encoded_width, encoder->encoded_height,
- 25, // TODO: framerate
+ static_cast<int>(encoder->encoded_width),
+ static_cast<int>(encoder->encoded_height),
+ static_cast<int>((framerate_denom + framerate_num / 2) / framerate_num),
0,
encoder_quality,
VVENC_MEDIUM);
@@ -482,6 +484,9 @@ static heif_error vvenc_start_sequence_encoding_intern(void* encoder_raw, const
params.m_internChromaFormat = VVENC_CHROMA_400;
}
+ params.m_FrameRate = framerate_num;
+ params.m_FrameScale = framerate_denom;
+
if (image_sequence) {
if (options->keyframe_distance_max) {
params.m_IntraPeriod = options->keyframe_distance_max;
@@ -750,7 +755,7 @@ static heif_error vvenc_encode_image(void* encoder_raw, const heif_image* image,
heif_image_input_class input_class)
{
heif_error err;
- err = vvenc_start_sequence_encoding_intern(encoder_raw, image, input_class, nullptr, false);
+ err = vvenc_start_sequence_encoding_intern(encoder_raw, image, input_class, 1,25, nullptr, false);
if (err.code) {
return err;
}
@@ -767,9 +772,10 @@ static heif_error vvenc_encode_image(void* encoder_raw, const heif_image* image,
static heif_error vvenc_start_sequence_encoding(void* encoder_raw, const heif_image* image,
enum heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options)
{
- return vvenc_start_sequence_encoding_intern(encoder_raw, image, input_class, options, true);
+ return vvenc_start_sequence_encoding_intern(encoder_raw, image, input_class, framerate_num, framerate_denom, options, true);
}
diff --git a/libheif/plugins/encoder_x264.cc b/libheif/plugins/encoder_x264.cc
index 247abcbd..bce1d522 100644
--- a/libheif/plugins/encoder_x264.cc
+++ b/libheif/plugins/encoder_x264.cc
@@ -710,6 +710,7 @@ static int rounded_size(int s)
static heif_error x264_start_sequence_encoding_intern(void* encoder_raw, const heif_image* image,
heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options,
bool image_sequence)
{
@@ -742,9 +743,8 @@ static heif_error x264_start_sequence_encoding_intern(void* encoder_raw, const h
}
- param.i_fps_num = 1; // TODO: set to sequence parameters
- param.i_fps_den = 1;
-
+ param.i_fps_num = framerate_num;
+ param.i_fps_den = framerate_denom;
if (options) {
if (options->keyframe_distance_min) {
@@ -943,9 +943,11 @@ static heif_error x264_start_sequence_encoding_intern(void* encoder_raw, const h
static heif_error x264_start_sequence_encoding(void* encoder_raw, const heif_image* image,
enum heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options)
{
- return x264_start_sequence_encoding_intern(encoder_raw, image, input_class, options, true);
+ return x264_start_sequence_encoding_intern(encoder_raw, image, input_class,
+ framerate_num, framerate_denom, options, true);
}
@@ -1060,7 +1062,7 @@ static heif_error x264_encode_image(void* encoder_raw, const heif_image* image,
heif_image_input_class input_class)
{
heif_error err;
- err = x264_start_sequence_encoding_intern(encoder_raw, image, input_class, nullptr, false);
+ err = x264_start_sequence_encoding_intern(encoder_raw, image, input_class, 1,25, nullptr, false);
if (err.code) {
return err;
}
diff --git a/libheif/plugins/encoder_x265.cc b/libheif/plugins/encoder_x265.cc
index b5d8e510..1c35c0a4 100644
--- a/libheif/plugins/encoder_x265.cc
+++ b/libheif/plugins/encoder_x265.cc
@@ -747,6 +747,7 @@ void encoder_struct_x265::append_nal_packets(x265_nal* nals, uint32_t num_nals,
static heif_error x265_start_sequence_encoding_intern(void* encoder_raw, const heif_image* image,
enum heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options,
bool image_sequence)
{
@@ -800,10 +801,6 @@ static heif_error x265_start_sequence_encoding_intern(void* encoder_raw, const h
}
- param->fpsNum = 1; // TODO: set to sequence parameters
- param->fpsDenom = 1;
-
-
// x265 cannot encode images smaller than one CTU size
// https://bitbucket.org/multicoreware/x265/issues/475/x265-does-not-allow-image-sizes-smaller
// -> use smaller CTU sizes for very small images
@@ -1024,6 +1021,8 @@ static heif_error x265_start_sequence_encoding_intern(void* encoder_raw, const h
param->sourceWidth = rounded_size(param->sourceWidth);
param->sourceHeight = rounded_size(param->sourceHeight);
+ param->fpsNum = framerate_num;
+ param->fpsDenom = framerate_denom;
encoder->bit_depth = bit_depth;
@@ -1050,9 +1049,11 @@ static heif_error x265_start_sequence_encoding_intern(void* encoder_raw, const h
static heif_error x265_start_sequence_encoding(void* encoder_raw, const heif_image* image,
enum heif_image_input_class input_class,
+ uint32_t framerate_num, uint32_t framerate_denom,
const heif_sequence_encoding_options* options)
{
- return x265_start_sequence_encoding_intern(encoder_raw, image, input_class, options, true);
+ return x265_start_sequence_encoding_intern(encoder_raw, image, input_class,
+ framerate_num, framerate_denom, options, true);
}
@@ -1188,7 +1189,7 @@ static heif_error x265_encode_image(void* encoder_raw, const heif_image* image,
heif_image_input_class input_class)
{
heif_error err;
- err = x265_start_sequence_encoding_intern(encoder_raw, image, input_class, nullptr, false);
+ err = x265_start_sequence_encoding_intern(encoder_raw, image, input_class, 1,25, nullptr, false);
if (err.code) {
return err;
}
diff --git a/libheif/sequences/track_visual.cc b/libheif/sequences/track_visual.cc
index 1b905f0f..a8a238ed 100644
--- a/libheif/sequences/track_visual.cc
+++ b/libheif/sequences/track_visual.cc
@@ -512,6 +512,7 @@ Error Track_Visual::encode_image(std::shared_ptr<HeifPixelImage> image,
Error encodeError = encoder->encode_sequence_frame(colorConvertedImage, h_encoder,
in_options ? *in_options : *local_dummy_options,
input_class,
+ colorConvertedImage->get_sample_duration(), get_timescale(),
m_current_frame_nr);
if (local_dummy_options) {
heif_sequence_encoding_options_release(local_dummy_options);