shithub: libvpx

Download patch

ref: 820201caa803e78c461e05128b87f4d7b24247a7
parent: 7fd2561d646e40735e8e6b0f55798903dac4568d
author: James Zern <jzern@google.com>
date: Wed Oct 16 12:10:27 EDT 2013

vp9_thread: add vp9_worker_execute()

cherry-picked from:
commit 988b70844e03efcfcc075a9bc25d846670494f36
Author: Pascal Massimino <pascal.massimino@gmail.com>
Date:   Fri Aug 2 11:15:16 2013 -0700

    add WebPWorkerExecute() for convenient bypass

    This is mainly for re-using the worker structs without using the
    thread.

    Change-Id: I8e1be29e53874ef425b15c192fb68036b4c0a359

Original source:
 http://git.chromium.org/webm/libwebp.git
 100644 blob c0d318aee628fdf9ba4876451a28aa978f1066b8 src/utils/thread.c
 100644 blob c2b92c9fe353f8e514f78922f3d237204a9cbc66 src/utils/thread.h

Change-Id: I13fe92b1e94062bb99fdeeb7cb0b4b0575d27793

--- a/test/vp9_thread_test.cc
+++ b/test/vp9_thread_test.cc
@@ -18,7 +18,7 @@
 
 namespace {
 
-class VP9WorkerThreadTest : public ::testing::Test {
+class VP9WorkerThreadTest : public ::testing::TestWithParam<bool> {
  protected:
   virtual ~VP9WorkerThreadTest() {}
   virtual void SetUp() {
@@ -38,7 +38,7 @@
   return *reinterpret_cast<int*>(return_value);
 }
 
-TEST_F(VP9WorkerThreadTest, HookSuccess) {
+TEST_P(VP9WorkerThreadTest, HookSuccess) {
   EXPECT_TRUE(vp9_worker_sync(&worker_));  // should be a no-op.
 
   for (int i = 0; i < 2; ++i) {
@@ -50,7 +50,12 @@
     worker_.data1 = &hook_data;
     worker_.data2 = &return_value;
 
-    vp9_worker_launch(&worker_);
+    const bool synchronous = GetParam();
+    if (synchronous) {
+      vp9_worker_execute(&worker_);
+    } else {
+      vp9_worker_launch(&worker_);
+    }
     EXPECT_TRUE(vp9_worker_sync(&worker_));
     EXPECT_FALSE(worker_.had_error);
     EXPECT_EQ(5, hook_data);
@@ -59,7 +64,7 @@
   }
 }
 
-TEST_F(VP9WorkerThreadTest, HookFailure) {
+TEST_P(VP9WorkerThreadTest, HookFailure) {
   EXPECT_TRUE(vp9_worker_reset(&worker_));
 
   int hook_data = 0;
@@ -68,7 +73,12 @@
   worker_.data1 = &hook_data;
   worker_.data2 = &return_value;
 
-  vp9_worker_launch(&worker_);
+  const bool synchronous = GetParam();
+  if (synchronous) {
+    vp9_worker_execute(&worker_);
+  } else {
+    vp9_worker_launch(&worker_);
+  }
   EXPECT_FALSE(vp9_worker_sync(&worker_));
   EXPECT_TRUE(worker_.had_error);
 
@@ -105,5 +115,7 @@
   }
   EXPECT_STREQ("b35a1b707b28e82be025d960aba039bc", md5.Get());
 }
+
+INSTANTIATE_TEST_CASE_P(Synchronous, VP9WorkerThreadTest, ::testing::Bool());
 
 }  // namespace
--- a/vp9/decoder/vp9_thread.c
+++ b/vp9/decoder/vp9_thread.c
@@ -145,9 +145,7 @@
       pthread_cond_wait(&worker->condition_, &worker->mutex_);
     }
     if (worker->status_ == WORK) {
-      if (worker->hook) {
-        worker->had_error |= !worker->hook(worker->data1, worker->data2);
-      }
+      vp9_worker_execute(worker);
       worker->status_ = OK;
     } else if (worker->status_ == NOT_OK) {   // finish the worker
       done = 1;
@@ -178,7 +176,7 @@
   pthread_mutex_unlock(&worker->mutex_);
 }
 
-#endif
+#endif  // CONFIG_MULTITHREAD
 
 //------------------------------------------------------------------------------
 
@@ -218,12 +216,17 @@
   return ok;
 }
 
+void vp9_worker_execute(VP9Worker* const worker) {
+  if (worker->hook != NULL) {
+    worker->had_error |= !worker->hook(worker->data1, worker->data2);
+  }
+}
+
 void vp9_worker_launch(VP9Worker* const worker) {
 #if CONFIG_MULTITHREAD
   change_state(worker, WORK);
 #else
-  if (worker->hook)
-    worker->had_error |= !worker->hook(worker->data1, worker->data2);
+  vp9_worker_execute(worker);
 #endif
 }
 
--- a/vp9/decoder/vp9_thread.h
+++ b/vp9/decoder/vp9_thread.h
@@ -80,6 +80,11 @@
 // hook/data1/data2 can be changed at any time before calling this function,
 // but not be changed afterward until the next call to vp9_worker_sync().
 void vp9_worker_launch(VP9Worker* const worker);
+// This function is similar to vp9_worker_launch() except that it calls the
+// hook directly instead of using a thread. Convenient to bypass the thread
+// mechanism while still using the VP9Worker structs. vp9_worker_sync() must
+// still be called afterward (for error reporting).
+void vp9_worker_execute(VP9Worker* const worker);
 // Kill the thread and terminate the object. To use the object again, one
 // must call vp9_worker_reset() again.
 void vp9_worker_end(VP9Worker* const worker);