[LMCS] Create separate pictures for LMCS mapped pixels

This commit is contained in:
Marko Viitanen 2021-05-05 13:28:39 +03:00
parent 703cb155cb
commit d2670ccdc8
4 changed files with 40 additions and 1 deletions

View file

@ -1305,7 +1305,12 @@ static void encoder_set_source_picture(encoder_state_t * const state, kvz_pictur
assert(!state->tile->frame->source); assert(!state->tile->frame->source);
assert(!state->tile->frame->rec); assert(!state->tile->frame->rec);
state->tile->frame->source_lmcs_mapped = false;
state->tile->frame->rec_lmcs_mapped = false;
state->tile->frame->source = frame; state->tile->frame->source = frame;
state->tile->frame->source_lmcs = state->tile->frame->source;
if (state->encoder_control->cfg.lossless) { if (state->encoder_control->cfg.lossless) {
// In lossless mode, the reconstruction is equal to the source frame. // In lossless mode, the reconstruction is equal to the source frame.
state->tile->frame->rec = kvz_image_copy_ref(frame); state->tile->frame->rec = kvz_image_copy_ref(frame);
@ -1314,6 +1319,12 @@ static void encoder_set_source_picture(encoder_state_t * const state, kvz_pictur
state->tile->frame->rec->dts = frame->dts; state->tile->frame->rec->dts = frame->dts;
state->tile->frame->rec->pts = frame->pts; state->tile->frame->rec->pts = frame->pts;
} }
state->tile->frame->rec_lmcs = state->tile->frame->rec;
if (state->encoder_control->cfg.lmcs_enable) {
state->tile->frame->source_lmcs = kvz_image_alloc(state->encoder_control->chroma_format, frame->width, frame->height);
state->tile->frame->rec_lmcs = kvz_image_alloc(state->encoder_control->chroma_format, frame->width, frame->height);
}
kvz_videoframe_set_poc(state->tile->frame, state->frame->poc); kvz_videoframe_set_poc(state->tile->frame, state->frame->poc);
} }
@ -1586,6 +1597,18 @@ static void encoder_state_init_new_frame(encoder_state_t * const state, kvz_pict
// ToDo: support other signal types in LMCS // ToDo: support other signal types in LMCS
kvz_lmcs_preanalyzer(state, state->tile->frame, state->slice->lmcs_aps, RESHAPE_SIGNAL_SDR); kvz_lmcs_preanalyzer(state, state->tile->frame, state->slice->lmcs_aps, RESHAPE_SIGNAL_SDR);
kvz_construct_reshaper_lmcs(state->slice->lmcs_aps); kvz_construct_reshaper_lmcs(state->slice->lmcs_aps);
kvz_pixel* luma = state->tile->frame->source->y;
kvz_pixel* luma_lmcs = state->tile->frame->source_lmcs->y;
for (int y = 0; y < state->tile->frame->source->height; y++) {
for (int x = 0; x < state->tile->frame->source->width; x++) {
luma_lmcs[x] = state->slice->lmcs_aps->m_fwdLUT[luma[x]];
}
luma += state->tile->frame->source->stride;
luma_lmcs += state->tile->frame->source->stride;
}
state->tile->frame->source_lmcs_mapped = true;
} }
encoder_state_init_children(state); encoder_state_init_children(state);

View file

@ -1294,7 +1294,6 @@ void kvz_encode_lmcs_adaptive_parameter_set(encoder_state_t* const state)
bitstream_t* const stream = &state->stream; bitstream_t* const stream = &state->stream;
if (state->encoder_control->cfg.lmcs_enable) { if (state->encoder_control->cfg.lmcs_enable) {
// ToDo: Write LMCS APS NAL
kvz_nal_write(stream, NAL_UNIT_PREFIX_APS, 0, state->frame->first_nal); kvz_nal_write(stream, NAL_UNIT_PREFIX_APS, 0, state->frame->first_nal);
state->frame->first_nal = false; state->frame->first_nal = false;

View file

@ -66,6 +66,18 @@ videoframe_t * kvz_videoframe_alloc(int32_t width,
*/ */
int kvz_videoframe_free(videoframe_t * const frame) int kvz_videoframe_free(videoframe_t * const frame)
{ {
// Free LMCS mapped images, they are either pointing to normal or allocated separately
if (frame->source_lmcs != frame->source) {
kvz_image_free(frame->source_lmcs);
frame->source_lmcs = NULL;
}
if (frame->rec_lmcs != frame->rec) {
kvz_image_free(frame->rec_lmcs);
frame->rec_lmcs = NULL;
}
kvz_image_free(frame->source); kvz_image_free(frame->source);
frame->source = NULL; frame->source = NULL;
kvz_image_free(frame->rec); kvz_image_free(frame->rec);

View file

@ -37,7 +37,9 @@
typedef struct videoframe typedef struct videoframe
{ {
kvz_picture *source; //!< \brief Source image. kvz_picture *source; //!< \brief Source image.
kvz_picture *source_lmcs; //!< \brief LMCS mapped source image if available, otherwise points to source.
kvz_picture *rec; //!< \brief Reconstructed image. kvz_picture *rec; //!< \brief Reconstructed image.
kvz_picture *rec_lmcs; //!< \brief LMCS mapped reconstructed image, if available, otherwise points to source.
int32_t width; //!< \brief Luma pixel array width. int32_t width; //!< \brief Luma pixel array width.
int32_t height; //!< \brief Luma pixel array height. int32_t height; //!< \brief Luma pixel array height.
@ -49,6 +51,9 @@ typedef struct videoframe
struct sao_info_t *sao_chroma; //!< \brief Array of sao parameters for every LCU. struct sao_info_t *sao_chroma; //!< \brief Array of sao parameters for every LCU.
struct alf_info_t *alf_info; //!< \brief Array of alf parameters for both luma and chroma. struct alf_info_t *alf_info; //!< \brief Array of alf parameters for both luma and chroma.
int32_t poc; //!< \brief Picture order count int32_t poc; //!< \brief Picture order count
bool source_lmcs_mapped; //!< \brief Indicate if source_lmcs is available and mapped to LMCS
bool rec_lmcs_mapped; //!< \brief Indicate if rec_lmcs is available and mapped to LMCS
} videoframe_t; } videoframe_t;