shithub: libvpx

Download patch

ref: ed11abbc364b303a34a6e9d9fbf936d4a33b1886
parent: a70861c43598fce722843f8e7c765b1b154fb17c
parent: a6efe6d43765756db2702bae3cc9f9ea0f26b69e
author: James Zern <jzern@google.com>
date: Fri Aug 26 19:48:08 EDT 2016

Merge changes I353da4a2,I423f2153

* changes:
  vp8_decoder_create_threads: check sem/pthread returns
  vp8_create_decoder_instances: add missing setjmp

--- a/vp8/decoder/onyxd_if.c
+++ b/vp8/decoder/onyxd_if.c
@@ -444,10 +444,17 @@
     if (!fb->pbi[0]) return VPX_CODEC_ERROR;
 
 #if CONFIG_MULTITHREAD
-    /* enable row-based threading only when use_frame_threads
-     * is disabled */
+    if (setjmp(fb->pbi[0]->common.error.jmp)) {
+      vp8_remove_decoder_instances(fb);
+      memset(fb->pbi, 0, sizeof(fb->pbi) / sizeof(fb->pbi[0]));
+      vp8_clear_system_state();
+      return VPX_CODEC_ERROR;
+    }
+
+    fb->pbi[0]->common.error.setjmp = 1;
     fb->pbi[0]->max_threads = oxcf->max_threads;
     vp8_decoder_create_threads(fb->pbi[0]);
+    fb->pbi[0]->common.error.setjmp = 0;
 #endif
   } else {
     /* TODO : create frame threads and decoder instances for each
--- a/vp8/decoder/threading.c
+++ b/vp8/decoder/threading.c
@@ -609,8 +609,13 @@
     CALLOC_ARRAY_ALIGNED(pbi->mb_row_di, pbi->decoding_thread_count, 32);
     CALLOC_ARRAY(pbi->de_thread_data, pbi->decoding_thread_count);
 
+    if (sem_init(&pbi->h_event_end_decoding, 0, 0)) {
+      vpx_internal_error(&pbi->common.error, VPX_CODEC_MEM_ERROR,
+                         "Failed to initialize semaphore");
+    }
+
     for (ithread = 0; ithread < pbi->decoding_thread_count; ++ithread) {
-      sem_init(&pbi->h_event_start_decoding[ithread], 0, 0);
+      if (sem_init(&pbi->h_event_start_decoding[ithread], 0, 0)) break;
 
       vp8_setup_block_dptrs(&pbi->mb_row_di[ithread].mbd);
 
@@ -618,13 +623,23 @@
       pbi->de_thread_data[ithread].ptr1 = (void *)pbi;
       pbi->de_thread_data[ithread].ptr2 = (void *)&pbi->mb_row_di[ithread];
 
-      pthread_create(&pbi->h_decoding_thread[ithread], 0, thread_decoding_proc,
-                     (&pbi->de_thread_data[ithread]));
+      if (pthread_create(&pbi->h_decoding_thread[ithread], 0,
+                         thread_decoding_proc, &pbi->de_thread_data[ithread])) {
+        sem_destroy(&pbi->h_event_start_decoding[ithread]);
+        break;
+      }
     }
 
-    sem_init(&pbi->h_event_end_decoding, 0, 0);
-
-    pbi->allocated_decoding_thread_count = pbi->decoding_thread_count;
+    pbi->allocated_decoding_thread_count = ithread;
+    if (pbi->allocated_decoding_thread_count != pbi->decoding_thread_count) {
+      /* the remainder of cleanup cases will be handled in
+       * vp8_decoder_remove_threads(). */
+      if (pbi->allocated_decoding_thread_count == 0) {
+        sem_destroy(&pbi->h_event_end_decoding);
+      }
+      vpx_internal_error(&pbi->common.error, VPX_CODEC_MEM_ERROR,
+                         "Failed to create threads");
+    }
   }
 }
 
@@ -770,7 +785,9 @@
       sem_destroy(&pbi->h_event_start_decoding[i]);
     }
 
-    sem_destroy(&pbi->h_event_end_decoding);
+    if (pbi->allocated_decoding_thread_count) {
+      sem_destroy(&pbi->h_event_end_decoding);
+    }
 
     vpx_free(pbi->h_decoding_thread);
     pbi->h_decoding_thread = NULL;
--- a/vp8/vp8_dx_iface.c
+++ b/vp8/vp8_dx_iface.c
@@ -342,7 +342,7 @@
     }
 
     res = vp8_create_decoder_instances(&ctx->yv12_frame_buffers, &oxcf);
-    ctx->decoder_init = 1;
+    if (res == VPX_CODEC_OK) ctx->decoder_init = 1;
   }
 
   /* Set these even if already initialized.  The caller may have changed the