Add comments and assertions to swap_frame_buffers.

Add a comment to describe how swap_frame_buffers() report failure.

Add assertions to swap_frame_buffers() to assert the assumptions it
makes.

Document the current meaning of pbi->hold_ref_buf.

BUG=aomedia:2179

Change-Id: Idc3d14f7e52e6d2ff645bfc6f63914429afa57cc
diff --git a/av1/decoder/decoder.c b/av1/decoder/decoder.c
index c6c439f..ba13741 100644
--- a/av1/decoder/decoder.c
+++ b/av1/decoder/decoder.c
@@ -17,6 +17,7 @@
 #include "config/aom_dsp_rtcd.h"
 #include "config/aom_scale_rtcd.h"
 
+#include "aom_dsp/aom_dsp_common.h"
 #include "aom_mem/aom_mem.h"
 #include "aom_ports/system_state.h"
 #include "aom_ports/aom_once.h"
@@ -325,7 +326,7 @@
 
   lock_buffer_pool(pool);
   // Release all the reference buffers if worker thread is holding them.
-  if (pbi->hold_ref_buf == 1) {
+  if (pbi->hold_ref_buf) {
     int ref_index = 0, mask;
     for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) {
       const int old_idx = cm->ref_frame_map[ref_index];
@@ -355,9 +356,11 @@
   unlock_buffer_pool(pool);
 }
 
-/* If any buffer updating is signaled it should be done here.
-   Consumes a reference to cm->new_fb_idx.
-*/
+// If any buffer updating is signaled it should be done here.
+// Consumes a reference to cm->new_fb_idx.
+//
+// This functions returns void. It reports failure by setting
+// cm->error.error_code.
 static void swap_frame_buffers(AV1Decoder *pbi, int frame_decoded) {
   int ref_index = 0, mask;
   AV1_COMMON *const cm = &pbi->common;
@@ -370,6 +373,12 @@
     // In ext-tile decoding, the camera frame header is only decoded once. So,
     // we don't release the references here.
     if (!pbi->camera_frame_header_ready) {
+      // If we are not holding reference buffers in cm->next_ref_frame_map,
+      // assert that the following two for loops are no-ops.
+      assert(IMPLIES(!pbi->hold_ref_buf, pbi->refresh_frame_flags == 0));
+      assert(IMPLIES(!pbi->hold_ref_buf,
+                     cm->show_existing_frame && !cm->reset_decoder_state));
+
       for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) {
         const int old_idx = cm->ref_frame_map[ref_index];
         // Current thread releases the holding of reference frame.
@@ -393,9 +402,8 @@
       }
     }
 
-    YV12_BUFFER_CONFIG *cur_frame = get_frame_new_buffer(cm);
-
     if (cm->show_existing_frame || cm->show_frame) {
+      YV12_BUFFER_CONFIG *cur_frame = get_frame_new_buffer(cm);
       if (pbi->output_all_layers) {
         // Append this frame to the output queue
         if (pbi->num_output_frames >= MAX_NUM_SPATIAL_LAYERS) {
@@ -424,6 +432,10 @@
 
     unlock_buffer_pool(pool);
   } else {
+    // The code here assumes we are not holding reference buffers in
+    // cm->next_ref_frame_map. If this assertion fails, we are leaking the
+    // frame buffer references in cm->next_ref_frame_map.
+    assert(IMPLIES(!pbi->camera_frame_header_ready, !pbi->hold_ref_buf));
     // Nothing was decoded, so just drop this frame buffer
     lock_buffer_pool(pool);
     decrease_ref_count(cm->new_fb_idx, frame_bufs, pool);
diff --git a/av1/decoder/decoder.h b/av1/decoder/decoder.h
index dcd8dcc..55506d6 100644
--- a/av1/decoder/decoder.h
+++ b/av1/decoder/decoder.h
@@ -207,7 +207,8 @@
   int max_threads;
   int inv_tile_order;
   int need_resync;   // wait for key/intra-only frame.
-  int hold_ref_buf;  // hold the reference buffer.
+  int hold_ref_buf;  // Boolean: whether we are holding reference buffers in
+                     // common.next_ref_frame_map.
 
   int tile_size_bytes;
   int tile_col_size_bytes;