Fix loopfilter race condition in multithreaded encoder
authorAttila Nagy <attilanagy@google.com>
Wed, 25 Apr 2012 11:04:55 +0000 (14:04 +0300)
committerAttila Nagy <attilanagy@google.com>
Wed, 25 Apr 2012 11:26:02 +0000 (14:26 +0300)
Race was introduced by https://gerrit.chromium.org/gerrit/15563.

If loopfilter related config params were changed between frames, or
after a KEY frame, there could be a mismatch between encoder's and
decoder's recontructed image. In worst case, when frame buffers are
reallocated because of a size change, the loopfilter could
do an invalid data access (segmentation fault).

Fixes:
Sync with the loopfilter before applying any encoder changes in
vp8_change_config().
Moved the loopfilter synching to the top of
encode_frame_to_data_rate() so that it's done before any alteration of
the encoder.

Change-Id: Ide5245d2a2aeed78752de750c0110bc4b46f5b7b

vp8/encoder/onyx_if.c

index ff01ff8..43caf20 100644 (file)
@@ -1412,6 +1412,15 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf)
     if (!oxcf)
         return;
 
+#if CONFIG_MULTITHREAD
+    /*  wait for the last picture loopfilter thread done */
+    if (cpi->b_lpf_running)
+    {
+        sem_wait(&cpi->h_event_end_lpf);
+        cpi->b_lpf_running = 0;
+    }
+#endif
+
     if (cm->version != oxcf->Version)
     {
         cm->version = oxcf->Version;
@@ -3194,6 +3203,15 @@ static void encode_frame_to_data_rate
     // Clear down mmx registers to allow floating point in what follows
     vp8_clear_system_state();
 
+#if CONFIG_MULTITHREAD
+    /*  wait for the last picture loopfilter thread done */
+    if (cpi->b_lpf_running)
+    {
+        sem_wait(&cpi->h_event_end_lpf);
+        cpi->b_lpf_running = 0;
+    }
+#endif
+
     // Test code for segmentation of gf/arf (0,0)
     //segmentation_test_function( cpi);
 
@@ -3748,14 +3766,7 @@ static void encode_frame_to_data_rate
             vp8_setup_key_frame(cpi);
         }
 
-#if CONFIG_MULTITHREAD
-        /*  wait for the last picture loopfilter thread done */
-        if (cpi->b_lpf_running)
-        {
-            sem_wait(&cpi->h_event_end_lpf);
-            cpi->b_lpf_running = 0;
-        }
-#endif
+
 
 #if CONFIG_REALTIME_ONLY & CONFIG_ONTHEFLY_BITPACKING
         {