FILM GRAIN: Move film grain parameters for Altref frames
When a hidden (Altref) frame is later used as a "show existing frame"
the current code stores the film grain parameters in the "show existing
frame". However, this requires a second full pass of the frame
to apply the parameters. It is more efficient to have the option of
applying the parameters at the time the Altref frame is being decoded.
To enable this we have made the following changes:
- a hidden frame signals if it can later be used as a "show existing
frame" by sending a new flag "showable_frame"
- a hidden frame with the "showable_frame" flag set sends the film
grain parameters in the hidden frame rather than in the show existing
frame. The parameters can be decoded at the time the hidden frame is
decoded.
Note: The experiment is still disabled by default. Enabling will be
a separate commit.
Change-Id: Ib24d13a5d2604b23917ab3417c37d5e5092433ac
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index cad191d..dfd3b50 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -2728,10 +2728,13 @@
#endif // CONFIG_TIMING_INFO_IN_SEQ_HEADERS
#if CONFIG_FILM_GRAIN
-static void write_film_grain_params(AV1_COMMON *const cm,
+static void write_film_grain_params(AV1_COMP *cpi,
struct aom_write_bit_buffer *wb) {
+ AV1_COMMON *const cm = &cpi->common;
aom_film_grain_t *pars = &cm->film_grain_params;
+ cm->cur_frame->film_grain_params = *pars;
+
aom_wb_write_bit(wb, pars->apply_grain);
if (!pars->apply_grain) return;
@@ -2742,7 +2745,27 @@
pars->random_seed += 1735;
aom_wb_write_bit(wb, pars->update_parameters);
+#if CONFIG_FILM_GRAIN_SHOWEX
+ if (!pars->update_parameters) {
+ RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
+ int ref_frame, ref_idx, buf_idx;
+ for (ref_frame = LAST_FRAME; ref_frame < TOTAL_REFS_PER_FRAME;
+ ref_frame++) {
+ ref_idx = get_ref_frame_map_idx(cpi, ref_frame);
+ assert(idx != INVALID_IDX);
+ buf_idx = cm->ref_frame_map[ref_idx];
+ if (frame_bufs[buf_idx].film_grain_params_present &&
+ memcmp(pars, &frame_bufs[buf_idx].film_grain_params, sizeof(*pars))) {
+ break;
+ }
+ }
+ assert(ref_frame < TOTAL_REFS_PER_FRAME);
+ aom_wb_write_literal(wb, ref_idx, 3);
+ return;
+ }
+#else
if (!pars->update_parameters) return;
+#endif
// Scaling functions parameters
@@ -3046,7 +3069,7 @@
aom_wb_write_literal(wb, 0, 8);
}
-#if CONFIG_FILM_GRAIN
+#if CONFIG_FILM_GRAIN && !CONFIG_FILM_GRAIN_SHOWEX
if (cm->film_grain_params_present && cm->show_frame) {
int flip_back_update_parameters_flag = 0;
if (cm->frame_type == KEY_FRAME &&
@@ -3054,7 +3077,7 @@
cm->film_grain_params.update_parameters = 1;
flip_back_update_parameters_flag = 1;
}
- write_film_grain_params(cm, wb);
+ write_film_grain_params(cpi, wb);
if (flip_back_update_parameters_flag)
cm->film_grain_params.update_parameters = 0;
@@ -3361,15 +3384,24 @@
if (!frame_is_intra_only(cm)) write_global_motion(cpi, wb);
+#if CONFIG_FILM_GRAIN_SHOWEX
+ if (!cm->show_frame) {
+ aom_wb_write_bit(wb, cm->showable_frame);
+ }
+#endif
#if CONFIG_FILM_GRAIN
+#if CONFIG_FILM_GRAIN_SHOWEX
+ if (cm->film_grain_params_present && (cm->show_frame || cm->showable_frame)) {
+#else
if (cm->film_grain_params_present && cm->show_frame) {
+#endif
int flip_back_update_parameters_flag = 0;
if (cm->frame_type == KEY_FRAME &&
cm->film_grain_params.update_parameters == 0) {
cm->film_grain_params.update_parameters = 1;
flip_back_update_parameters_flag = 1;
}
- write_film_grain_params(cm, wb);
+ write_film_grain_params(cpi, wb);
if (flip_back_update_parameters_flag)
cm->film_grain_params.update_parameters = 0;