shithub: libvpx

Download patch

ref: d1b6fa41615611f24fa98e896ed94df91f6c6e1e
parent: ff61cbc5105c16d48ffd291cd85a031cbce36be9
author: Scott LaVarnway <slavarnway@google.com>
date: Tue Aug 14 08:00:23 EDT 2012

Added error checking to vp8cx_create_encoder_threads()

Added checks for pthread_create() errors.

Change-Id: Ie198ef5c14314fe252d2e02f7fe5bfacc7e16377

--- a/vp8/encoder/ethreading.c
+++ b/vp8/encoder/ethreading.c
@@ -484,7 +484,7 @@
     }
 }
 
-void vp8cx_create_encoder_threads(VP8_COMP *cpi)
+int vp8cx_create_encoder_threads(VP8_COMP *cpi)
 {
     const VP8_COMMON * cm = &cpi->common;
 
@@ -496,6 +496,7 @@
     {
         int ithread;
         int th_count = cpi->oxcf.multi_threaded - 1;
+        int rc = 0;
 
         /* don't allocate more threads than cores available */
         if (cpi->oxcf.multi_threaded > cm->processor_core_count)
@@ -509,11 +510,14 @@
         }
 
         if(th_count == 0)
-            return;
+            return 0;
 
-        CHECK_MEM_ERROR(cpi->h_encoding_thread, vpx_malloc(sizeof(pthread_t) * th_count));
-        CHECK_MEM_ERROR(cpi->h_event_start_encoding, vpx_malloc(sizeof(sem_t) * th_count));
-        CHECK_MEM_ERROR(cpi->mb_row_ei, vpx_memalign(32, sizeof(MB_ROW_COMP) * th_count));
+        CHECK_MEM_ERROR(cpi->h_encoding_thread,
+                        vpx_malloc(sizeof(pthread_t) * th_count));
+        CHECK_MEM_ERROR(cpi->h_event_start_encoding,
+                        vpx_malloc(sizeof(sem_t) * th_count));
+        CHECK_MEM_ERROR(cpi->mb_row_ei,
+                        vpx_memalign(32, sizeof(MB_ROW_COMP) * th_count));
         vpx_memset(cpi->mb_row_ei, 0, sizeof(MB_ROW_COMP) * th_count);
         CHECK_MEM_ERROR(cpi->en_thread_data,
                         vpx_malloc(sizeof(ENCODETHREAD_DATA) * th_count));
@@ -542,10 +546,34 @@
             ethd->ptr1 = (void *)cpi;
             ethd->ptr2 = (void *)&cpi->mb_row_ei[ithread];
 
-            pthread_create(&cpi->h_encoding_thread[ithread], 0, thread_encoding_proc, ethd);
+            rc = pthread_create(&cpi->h_encoding_thread[ithread], 0,
+                                thread_encoding_proc, ethd);
+            if(rc)
+                break;
         }
 
+        if(rc)
         {
+            /* shutdown other threads */
+            cpi->b_multi_threaded = 0;
+            for(--ithread; ithread >= 0; ithread--)
+            {
+                pthread_join(cpi->h_encoding_thread[ithread], 0);
+                sem_destroy(&cpi->h_event_start_encoding[ithread]);
+            }
+            sem_destroy(&cpi->h_event_end_encoding);
+
+            /* free thread related resources */
+            vpx_free(cpi->h_event_start_encoding);
+            vpx_free(cpi->h_encoding_thread);
+            vpx_free(cpi->mb_row_ei);
+            vpx_free(cpi->en_thread_data);
+
+            return -1;
+        }
+
+
+        {
             LPFTHREAD_DATA * lpfthd = &cpi->lpf_thread_data;
 
             sem_init(&cpi->h_event_start_lpf, 0, 0);
@@ -552,10 +580,34 @@
             sem_init(&cpi->h_event_end_lpf, 0, 0);
 
             lpfthd->ptr1 = (void *)cpi;
-            pthread_create(&cpi->h_filter_thread, 0, thread_loopfilter, lpfthd);
+            rc = pthread_create(&cpi->h_filter_thread, 0, thread_loopfilter,
+                                lpfthd);
+
+            if(rc)
+            {
+                /* shutdown other threads */
+                cpi->b_multi_threaded = 0;
+                for(--ithread; ithread >= 0; ithread--)
+                {
+                    sem_post(&cpi->h_event_start_encoding[ithread]);
+                    pthread_join(cpi->h_encoding_thread[ithread], 0);
+                    sem_destroy(&cpi->h_event_start_encoding[ithread]);
+                }
+                sem_destroy(&cpi->h_event_end_encoding);
+                sem_destroy(&cpi->h_event_end_lpf);
+                sem_destroy(&cpi->h_event_start_lpf);
+
+                /* free thread related resources */
+                vpx_free(cpi->h_event_start_encoding);
+                vpx_free(cpi->h_encoding_thread);
+                vpx_free(cpi->mb_row_ei);
+                vpx_free(cpi->en_thread_data);
+
+                return -2;
+            }
         }
     }
-
+    return 0;
 }
 
 void vp8cx_remove_encoder_threads(VP8_COMP *cpi)
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -56,7 +56,7 @@
 extern void print_parms(VP8_CONFIG *ocf, char *filenam);
 extern unsigned int vp8_get_processor_freq();
 extern void print_tree_update_probs();
-extern void vp8cx_create_encoder_threads(VP8_COMP *cpi);
+extern int vp8cx_create_encoder_threads(VP8_COMP *cpi);
 extern void vp8cx_remove_encoder_threads(VP8_COMP *cpi);
 
 int vp8_estimate_entropy_savings(VP8_COMP *cpi);
@@ -1954,7 +1954,11 @@
 #endif
 
 #if CONFIG_MULTITHREAD
-    vp8cx_create_encoder_threads(cpi);
+    if(vp8cx_create_encoder_threads(cpi))
+    {
+        vp8_remove_compressor(&cpi);
+        return 0;
+    }
 #endif
 
     cpi->fn_ptr[BLOCK_16X16].sdf            = vp8_sad16x16;