Improve signaling of pbi->row_mt_cond_.

This CL reduces the thread wakeup overhead of row_mt_worker_hook() and
documents how the bit-stream parsing and decoding of superblocks are
synchronized.

Call pthread_cond_signal(), not pthread_cond_broadcast(), to wake up
only one waiting thread to handle a new superblock decode job.

Note: The code this CL modifies was originally added in
commit 36ff5b12d237d7d6ba95f2478f04df1788dd5b5d;
https://aomedia-review.googlesource.com/c/aom/+/64241

Change-Id: Icdbaea86b5e24fc51724b6bff0d6be9157d27fb4
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 2c13564..04992c7 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -3346,6 +3346,16 @@
   return !td->xd.corrupted;
 }
 
+// The caller must hold pbi->row_mt_mutex_ when calling this function.
+// Returns 1 if either the next job is stored in *next_job_info or 1 is stored
+// in *end_of_frame.
+// NOTE: The caller waits on pbi->row_mt_cond_ if this function returns 0.
+// The return value of this function depends on the following variables:
+// - frame_row_mt_info->mi_rows_parse_done
+// - frame_row_mt_info->mi_rows_decode_started
+// - frame_row_mt_info->row_mt_exit
+// Therefore we may need to signal or broadcast pbi->row_mt_cond_ if any of
+// these variables is modified.
 static int get_next_job_info(AV1Decoder *const pbi,
                              AV1DecRowMTJobInfo *next_job_info,
                              int *end_of_frame) {
@@ -3380,9 +3390,10 @@
   }
 
   // Decoding cannot start as bit-stream parsing is not complete.
-  if (frame_row_mt_info->mi_rows_parse_done -
-          frame_row_mt_info->mi_rows_decode_started ==
-      0)
+  assert(frame_row_mt_info->mi_rows_parse_done >=
+         frame_row_mt_info->mi_rows_decode_started);
+  if (frame_row_mt_info->mi_rows_parse_done ==
+      frame_row_mt_info->mi_rows_decode_started)
     return 0;
 
   // Choose the tile to decode.
@@ -3435,6 +3446,14 @@
   dec_row_mt_sync->num_threads_working++;
   dec_row_mt_sync->mi_rows_decode_started += sb_mi_size;
   frame_row_mt_info->mi_rows_decode_started += sb_mi_size;
+  assert(frame_row_mt_info->mi_rows_parse_done >=
+         frame_row_mt_info->mi_rows_decode_started);
+#if CONFIG_MULTITHREAD
+  if (frame_row_mt_info->mi_rows_decode_started ==
+      frame_row_mt_info->mi_rows_to_decode) {
+    pthread_cond_broadcast(pbi->row_mt_cond_);
+  }
+#endif
 
   return 1;
 }
@@ -3446,10 +3465,16 @@
 #if CONFIG_MULTITHREAD
   pthread_mutex_lock(pbi->row_mt_mutex_);
 #endif
+  assert(frame_row_mt_info->mi_rows_parse_done >=
+         frame_row_mt_info->mi_rows_decode_started);
   tile_data->dec_row_mt_sync.mi_rows_parse_done += sb_mi_size;
   frame_row_mt_info->mi_rows_parse_done += sb_mi_size;
 #if CONFIG_MULTITHREAD
-  pthread_cond_broadcast(pbi->row_mt_cond_);
+  // A new decode job is available. Wake up one worker thread to handle the
+  // new decode job.
+  // NOTE: This assumes we bump mi_rows_parse_done and mi_rows_decode_started
+  // by the same increment (sb_mi_size).
+  pthread_cond_signal(pbi->row_mt_cond_);
   pthread_mutex_unlock(pbi->row_mt_mutex_);
 #endif
 }
diff --git a/av1/decoder/decoder.h b/av1/decoder/decoder.h
index 5ca939c..f16e75b 100644
--- a/av1/decoder/decoder.h
+++ b/av1/decoder/decoder.h
@@ -97,9 +97,26 @@
   int tile_cols_end;
   int start_tile;
   int end_tile;
-  int mi_rows_parse_done;
-  int mi_rows_decode_started;
   int mi_rows_to_decode;
+
+  // Invariant:
+  //   mi_rows_parse_done >= mi_rows_decode_started.
+  // mi_rows_parse_done and mi_rows_decode_started are both initialized to 0.
+  // mi_rows_parse_done is incremented freely. mi_rows_decode_started may only
+  // be incremented to catch up with mi_rows_parse_done but is not allowed to
+  // surpass mi_rows_parse_done.
+  //
+  // When mi_rows_decode_started reaches mi_rows_to_decode, there are no more
+  // decode jobs.
+
+  // Indicates the progress of the bit-stream parsing of superblocks.
+  // Initialized to 0. Incremented by sb_mi_size when parse sb row is done.
+  int mi_rows_parse_done;
+  // Indicates the progress of the decoding of superblocks.
+  // Initialized to 0. Incremented by sb_mi_size when decode sb row is started.
+  int mi_rows_decode_started;
+  // Boolean: Initialized to 0 (false). Set to 1 (true) on error to abort
+  // decoding.
   int row_mt_exit;
 } AV1DecRowMTInfo;