Wrap around current_video_frame and frame_offset

We removed resetting of current_video_frame when a keyframe is
inserted at decoder. And current_video_frame continues to
accumulate, which will overflow eventually, leading to mismatches
because of incorrect frame distance computation.

It may not be a big issue for encoder, since we still reset
current_video_frame to 0 when a keyframe is inserted.
And in a typical coding setting, we insert keyframe every
150 frames. So current_video_frame will not overflow.

Hence, we wrap the current_video_frame and frame_offset to a small
random value at decoder, when they reach a predefined limit
FRAME_NUM_LIMIT = INT_MAX - MAX_FRAME_OFFSET - 1.

In reality, it is unlikely to code so many frames and thus unable
to test. I therefore set FRAME_NUM_LIMIT = 20 and testes the coding
result locally with speed 2. It is the same as baseline.

Change-Id: I42928a5154319f0faf87251cd57c0094c605cf41
diff --git a/av1/common/enums.h b/av1/common/enums.h
index d48d0fd..6d95a84 100644
--- a/av1/common/enums.h
+++ b/av1/common/enums.h
@@ -93,6 +93,8 @@
 #define DIST_PRECISION (1 << DIST_PRECISION_BITS)  // 16
 #endif                                             // CONFIG_JNT_COMP
 
+#define FRAME_NUM_LIMIT (INT_MAX - MAX_FRAME_DISTANCE - 1)
+
 // Bitstream profiles indicated by 2-3 bits in the uncompressed header.
 // 00: Profile 0.  8-bit 4:2:0 only.
 // 10: Profile 1.  8-bit 4:4:4, 4:2:2, and 4:4:0.
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index c0dad11..a3a5a88 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -2608,6 +2608,30 @@
          TOTAL_REFS_PER_FRAME * sizeof(WarpedMotionParams));
 }
 
+// Copied from av1/encoder/random.h
+static INLINE unsigned int lcg_rand16(unsigned int *state) {
+  *state = (unsigned int)(*state * 1103515245ULL + 12345);
+  return *state / 65536 % 32768;
+}
+
+// Wrap around to make sure current_video_frame won't surpass a limit
+// Such that distance computation could remain correct
+static void wrap_around_current_video_frame(AV1Decoder *pbi) {
+  AV1_COMMON *const cm = &pbi->common;
+
+  if (cm->current_video_frame >= FRAME_NUM_LIMIT) {
+    // Wrap to a random number in range (MAX_FRAME_DISTANCE, 32768)
+    static unsigned int seed = 54321;
+    int new_frame_offset = lcg_rand16(&seed);
+    new_frame_offset += (MAX_FRAME_DISTANCE + 1);
+
+    // Wrap around for current frame
+    cm->current_video_frame = new_frame_offset;
+    cm->frame_offset = new_frame_offset;
+    cm->cur_frame->cur_frame_offset = cm->frame_offset;
+  }
+}
+
 #if CONFIG_FWD_KF
 static void show_existing_frame_reset(AV1Decoder *const pbi) {
   AV1_COMMON *const cm = &pbi->common;
@@ -2616,6 +2640,7 @@
 
   assert(cm->show_existing_frame);
 
+  wrap_around_current_video_frame(pbi);
   cm->frame_type = KEY_FRAME;
   cm->frame_offset = cm->current_video_frame;
 
@@ -2834,6 +2859,7 @@
 #endif  // CONFIG_FRAME_REFS_SIGNALING
 
   if (cm->frame_type == KEY_FRAME) {
+    wrap_around_current_video_frame(pbi);
     pbi->refresh_frame_flags = (1 << REF_FRAMES) - 1;
 
     for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {