summaryrefslogtreecommitdiff
path: root/vp9/common
diff options
context:
space:
mode:
authorJingning Han <jingning@google.com>2015-07-01 14:58:13 -0700
committerJingning Han <jingning@google.com>2015-07-01 17:45:49 -0700
commit3a3b0be09a11a9db7d2c1322cfbb8bd9b670a079 (patch)
tree11e6cec7997af7d87decccbeee246f3105c48dbc /vp9/common
parentfc5f3b8f4f170a32207ca2eca60f87bb0a01d03c (diff)
downloadlibvpx-3a3b0be09a11a9db7d2c1322cfbb8bd9b670a079.tar
libvpx-3a3b0be09a11a9db7d2c1322cfbb8bd9b670a079.tar.gz
libvpx-3a3b0be09a11a9db7d2c1322cfbb8bd9b670a079.tar.bz2
libvpx-3a3b0be09a11a9db7d2c1322cfbb8bd9b670a079.zip
Move multi-threading module functions into vpx_thread folder
This commit moves the primitive multi-threading files from vp9 folder to vpx_thread, which will be accessible by all vpx codec. Change-Id: Ib51e66e9c69801c10631fab56d35a0c0aaed5883
Diffstat (limited to 'vp9/common')
-rw-r--r--vp9/common/vp9_onyxc_int.h2
-rw-r--r--vp9/common/vp9_thread.c184
-rw-r--r--vp9/common/vp9_thread.h223
-rw-r--r--vp9/common/vp9_thread_common.h2
4 files changed, 2 insertions, 409 deletions
diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h
index 1811d76df..c5e2b3ab4 100644
--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -13,6 +13,7 @@
#include "./vpx_config.h"
#include "vpx/internal/vpx_codec_internal.h"
+#include "vpx_thread/vpx_thread.h"
#include "./vp9_rtcd.h"
#include "vp9/common/vp9_alloccommon.h"
#include "vp9/common/vp9_loopfilter.h"
@@ -21,7 +22,6 @@
#include "vp9/common/vp9_entropymode.h"
#include "vp9/common/vp9_frame_buffers.h"
#include "vp9/common/vp9_quant_common.h"
-#include "vp9/common/vp9_thread.h"
#include "vp9/common/vp9_tile_common.h"
#if CONFIG_VP9_POSTPROC
diff --git a/vp9/common/vp9_thread.c b/vp9/common/vp9_thread.c
deleted file mode 100644
index 1c6aec032..000000000
--- a/vp9/common/vp9_thread.c
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2013 Google Inc. All Rights Reserved.
-//
-// Use of this source code is governed by a BSD-style license
-// that can be found in the COPYING file in the root of the source
-// tree. An additional intellectual property rights grant can be found
-// in the file PATENTS. All contributing project authors may
-// be found in the AUTHORS file in the root of the source tree.
-// -----------------------------------------------------------------------------
-//
-// Multi-threaded worker
-//
-// Original source:
-// http://git.chromium.org/webm/libwebp.git
-// 100644 blob 264210ba2807e4da47eb5d18c04cf869d89b9784 src/utils/thread.c
-
-#include <assert.h>
-#include <string.h> // for memset()
-#include "./vp9_thread.h"
-#include "vpx_mem/vpx_mem.h"
-
-#if CONFIG_MULTITHREAD
-
-struct VP9WorkerImpl {
- pthread_mutex_t mutex_;
- pthread_cond_t condition_;
- pthread_t thread_;
-};
-
-//------------------------------------------------------------------------------
-
-static void execute(VP9Worker *const worker); // Forward declaration.
-
-static THREADFN thread_loop(void *ptr) {
- VP9Worker *const worker = (VP9Worker*)ptr;
- int done = 0;
- while (!done) {
- pthread_mutex_lock(&worker->impl_->mutex_);
- while (worker->status_ == OK) { // wait in idling mode
- pthread_cond_wait(&worker->impl_->condition_, &worker->impl_->mutex_);
- }
- if (worker->status_ == WORK) {
- execute(worker);
- worker->status_ = OK;
- } else if (worker->status_ == NOT_OK) { // finish the worker
- done = 1;
- }
- // signal to the main thread that we're done (for sync())
- pthread_cond_signal(&worker->impl_->condition_);
- pthread_mutex_unlock(&worker->impl_->mutex_);
- }
- return THREAD_RETURN(NULL); // Thread is finished
-}
-
-// main thread state control
-static void change_state(VP9Worker *const worker,
- VP9WorkerStatus new_status) {
- // No-op when attempting to change state on a thread that didn't come up.
- // Checking status_ without acquiring the lock first would result in a data
- // race.
- if (worker->impl_ == NULL) return;
-
- pthread_mutex_lock(&worker->impl_->mutex_);
- if (worker->status_ >= OK) {
- // wait for the worker to finish
- while (worker->status_ != OK) {
- pthread_cond_wait(&worker->impl_->condition_, &worker->impl_->mutex_);
- }
- // assign new status and release the working thread if needed
- if (new_status != OK) {
- worker->status_ = new_status;
- pthread_cond_signal(&worker->impl_->condition_);
- }
- }
- pthread_mutex_unlock(&worker->impl_->mutex_);
-}
-
-#endif // CONFIG_MULTITHREAD
-
-//------------------------------------------------------------------------------
-
-static void init(VP9Worker *const worker) {
- memset(worker, 0, sizeof(*worker));
- worker->status_ = NOT_OK;
-}
-
-static int sync(VP9Worker *const worker) {
-#if CONFIG_MULTITHREAD
- change_state(worker, OK);
-#endif
- assert(worker->status_ <= OK);
- return !worker->had_error;
-}
-
-static int reset(VP9Worker *const worker) {
- int ok = 1;
- worker->had_error = 0;
- if (worker->status_ < OK) {
-#if CONFIG_MULTITHREAD
- worker->impl_ = (VP9WorkerImpl*)vpx_calloc(1, sizeof(*worker->impl_));
- if (worker->impl_ == NULL) {
- return 0;
- }
- if (pthread_mutex_init(&worker->impl_->mutex_, NULL)) {
- goto Error;
- }
- if (pthread_cond_init(&worker->impl_->condition_, NULL)) {
- pthread_mutex_destroy(&worker->impl_->mutex_);
- goto Error;
- }
- pthread_mutex_lock(&worker->impl_->mutex_);
- ok = !pthread_create(&worker->impl_->thread_, NULL, thread_loop, worker);
- if (ok) worker->status_ = OK;
- pthread_mutex_unlock(&worker->impl_->mutex_);
- if (!ok) {
- pthread_mutex_destroy(&worker->impl_->mutex_);
- pthread_cond_destroy(&worker->impl_->condition_);
- Error:
- vpx_free(worker->impl_);
- worker->impl_ = NULL;
- return 0;
- }
-#else
- worker->status_ = OK;
-#endif
- } else if (worker->status_ > OK) {
- ok = sync(worker);
- }
- assert(!ok || (worker->status_ == OK));
- return ok;
-}
-
-static void execute(VP9Worker *const worker) {
- if (worker->hook != NULL) {
- worker->had_error |= !worker->hook(worker->data1, worker->data2);
- }
-}
-
-static void launch(VP9Worker *const worker) {
-#if CONFIG_MULTITHREAD
- change_state(worker, WORK);
-#else
- execute(worker);
-#endif
-}
-
-static void end(VP9Worker *const worker) {
-#if CONFIG_MULTITHREAD
- if (worker->impl_ != NULL) {
- change_state(worker, NOT_OK);
- pthread_join(worker->impl_->thread_, NULL);
- pthread_mutex_destroy(&worker->impl_->mutex_);
- pthread_cond_destroy(&worker->impl_->condition_);
- vpx_free(worker->impl_);
- worker->impl_ = NULL;
- }
-#else
- worker->status_ = NOT_OK;
- assert(worker->impl_ == NULL);
-#endif
- assert(worker->status_ == NOT_OK);
-}
-
-//------------------------------------------------------------------------------
-
-static VP9WorkerInterface g_worker_interface = {
- init, reset, sync, launch, execute, end
-};
-
-int vp9_set_worker_interface(const VP9WorkerInterface* const winterface) {
- if (winterface == NULL ||
- winterface->init == NULL || winterface->reset == NULL ||
- winterface->sync == NULL || winterface->launch == NULL ||
- winterface->execute == NULL || winterface->end == NULL) {
- return 0;
- }
- g_worker_interface = *winterface;
- return 1;
-}
-
-const VP9WorkerInterface *vp9_get_worker_interface(void) {
- return &g_worker_interface;
-}
-
-//------------------------------------------------------------------------------
diff --git a/vp9/common/vp9_thread.h b/vp9/common/vp9_thread.h
deleted file mode 100644
index 12848fede..000000000
--- a/vp9/common/vp9_thread.h
+++ /dev/null
@@ -1,223 +0,0 @@
-// Copyright 2013 Google Inc. All Rights Reserved.
-//
-// Use of this source code is governed by a BSD-style license
-// that can be found in the COPYING file in the root of the source
-// tree. An additional intellectual property rights grant can be found
-// in the file PATENTS. All contributing project authors may
-// be found in the AUTHORS file in the root of the source tree.
-// -----------------------------------------------------------------------------
-//
-// Multi-threaded worker
-//
-// Original source:
-// http://git.chromium.org/webm/libwebp.git
-// 100644 blob 7bd451b124ae3b81596abfbcc823e3cb129d3a38 src/utils/thread.h
-
-#ifndef VP9_DECODER_VP9_THREAD_H_
-#define VP9_DECODER_VP9_THREAD_H_
-
-#include "./vpx_config.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Set maximum decode threads to be 8 due to the limit of frame buffers
-// and not enough semaphores in the emulation layer on windows.
-#define MAX_DECODE_THREADS 8
-
-#if CONFIG_MULTITHREAD
-
-#if defined(_WIN32) && !HAVE_PTHREAD_H
-#include <errno.h> // NOLINT
-#include <process.h> // NOLINT
-#include <windows.h> // NOLINT
-typedef HANDLE pthread_t;
-typedef CRITICAL_SECTION pthread_mutex_t;
-typedef struct {
- HANDLE waiting_sem_;
- HANDLE received_sem_;
- HANDLE signal_event_;
-} pthread_cond_t;
-
-//------------------------------------------------------------------------------
-// simplistic pthread emulation layer
-
-// _beginthreadex requires __stdcall
-#define THREADFN unsigned int __stdcall
-#define THREAD_RETURN(val) (unsigned int)((DWORD_PTR)val)
-
-static INLINE int pthread_create(pthread_t* const thread, const void* attr,
- unsigned int (__stdcall *start)(void*),
- void* arg) {
- (void)attr;
- *thread = (pthread_t)_beginthreadex(NULL, /* void *security */
- 0, /* unsigned stack_size */
- start,
- arg,
- 0, /* unsigned initflag */
- NULL); /* unsigned *thrdaddr */
- if (*thread == NULL) return 1;
- SetThreadPriority(*thread, THREAD_PRIORITY_ABOVE_NORMAL);
- return 0;
-}
-
-static INLINE int pthread_join(pthread_t thread, void** value_ptr) {
- (void)value_ptr;
- return (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0 ||
- CloseHandle(thread) == 0);
-}
-
-// Mutex
-static INLINE int pthread_mutex_init(pthread_mutex_t *const mutex,
- void* mutexattr) {
- (void)mutexattr;
- InitializeCriticalSection(mutex);
- return 0;
-}
-
-static INLINE int pthread_mutex_trylock(pthread_mutex_t *const mutex) {
- return TryEnterCriticalSection(mutex) ? 0 : EBUSY;
-}
-
-static INLINE int pthread_mutex_lock(pthread_mutex_t *const mutex) {
- EnterCriticalSection(mutex);
- return 0;
-}
-
-static INLINE int pthread_mutex_unlock(pthread_mutex_t *const mutex) {
- LeaveCriticalSection(mutex);
- return 0;
-}
-
-static INLINE int pthread_mutex_destroy(pthread_mutex_t *const mutex) {
- DeleteCriticalSection(mutex);
- return 0;
-}
-
-// Condition
-static INLINE int pthread_cond_destroy(pthread_cond_t *const condition) {
- int ok = 1;
- ok &= (CloseHandle(condition->waiting_sem_) != 0);
- ok &= (CloseHandle(condition->received_sem_) != 0);
- ok &= (CloseHandle(condition->signal_event_) != 0);
- return !ok;
-}
-
-static INLINE int pthread_cond_init(pthread_cond_t *const condition,
- void* cond_attr) {
- (void)cond_attr;
- condition->waiting_sem_ = CreateSemaphore(NULL, 0, MAX_DECODE_THREADS, NULL);
- condition->received_sem_ = CreateSemaphore(NULL, 0, MAX_DECODE_THREADS, NULL);
- condition->signal_event_ = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (condition->waiting_sem_ == NULL ||
- condition->received_sem_ == NULL ||
- condition->signal_event_ == NULL) {
- pthread_cond_destroy(condition);
- return 1;
- }
- return 0;
-}
-
-static INLINE int pthread_cond_signal(pthread_cond_t *const condition) {
- int ok = 1;
- if (WaitForSingleObject(condition->waiting_sem_, 0) == WAIT_OBJECT_0) {
- // a thread is waiting in pthread_cond_wait: allow it to be notified
- ok = SetEvent(condition->signal_event_);
- // wait until the event is consumed so the signaler cannot consume
- // the event via its own pthread_cond_wait.
- ok &= (WaitForSingleObject(condition->received_sem_, INFINITE) !=
- WAIT_OBJECT_0);
- }
- return !ok;
-}
-
-static INLINE int pthread_cond_wait(pthread_cond_t *const condition,
- pthread_mutex_t *const mutex) {
- int ok;
- // note that there is a consumer available so the signal isn't dropped in
- // pthread_cond_signal
- if (!ReleaseSemaphore(condition->waiting_sem_, 1, NULL))
- return 1;
- // now unlock the mutex so pthread_cond_signal may be issued
- pthread_mutex_unlock(mutex);
- ok = (WaitForSingleObject(condition->signal_event_, INFINITE) ==
- WAIT_OBJECT_0);
- ok &= ReleaseSemaphore(condition->received_sem_, 1, NULL);
- pthread_mutex_lock(mutex);
- return !ok;
-}
-#else // _WIN32
-#include <pthread.h> // NOLINT
-# define THREADFN void*
-# define THREAD_RETURN(val) val
-#endif
-
-#endif // CONFIG_MULTITHREAD
-
-// State of the worker thread object
-typedef enum {
- NOT_OK = 0, // object is unusable
- OK, // ready to work
- WORK // busy finishing the current task
-} VP9WorkerStatus;
-
-// Function to be called by the worker thread. Takes two opaque pointers as
-// arguments (data1 and data2), and should return false in case of error.
-typedef int (*VP9WorkerHook)(void*, void*);
-
-// Platform-dependent implementation details for the worker.
-typedef struct VP9WorkerImpl VP9WorkerImpl;
-
-// Synchronization object used to launch job in the worker thread
-typedef struct {
- VP9WorkerImpl *impl_;
- VP9WorkerStatus status_;
- VP9WorkerHook hook; // hook to call
- void *data1; // first argument passed to 'hook'
- void *data2; // second argument passed to 'hook'
- int had_error; // return value of the last call to 'hook'
-} VP9Worker;
-
-// The interface for all thread-worker related functions. All these functions
-// must be implemented.
-typedef struct {
- // Must be called first, before any other method.
- void (*init)(VP9Worker *const worker);
- // Must be called to initialize the object and spawn the thread. Re-entrant.
- // Will potentially launch the thread. Returns false in case of error.
- int (*reset)(VP9Worker *const worker);
- // Makes sure the previous work is finished. Returns true if worker->had_error
- // was not set and no error condition was triggered by the working thread.
- int (*sync)(VP9Worker *const worker);
- // Triggers the thread to call hook() with data1 and data2 arguments. These
- // hook/data1/data2 values can be changed at any time before calling this
- // function, but not be changed afterward until the next call to Sync().
- void (*launch)(VP9Worker *const worker);
- // This function is similar to 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. sync() must
- // still be called afterward (for error reporting).
- void (*execute)(VP9Worker *const worker);
- // Kill the thread and terminate the object. To use the object again, one
- // must call reset() again.
- void (*end)(VP9Worker *const worker);
-} VP9WorkerInterface;
-
-// Install a new set of threading functions, overriding the defaults. This
-// should be done before any workers are started, i.e., before any encoding or
-// decoding takes place. The contents of the interface struct are copied, it
-// is safe to free the corresponding memory after this call. This function is
-// not thread-safe. Return false in case of invalid pointer or methods.
-int vp9_set_worker_interface(const VP9WorkerInterface *const winterface);
-
-// Retrieve the currently set thread worker interface.
-const VP9WorkerInterface *vp9_get_worker_interface(void);
-
-//------------------------------------------------------------------------------
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // VP9_DECODER_VP9_THREAD_H_
diff --git a/vp9/common/vp9_thread_common.h b/vp9/common/vp9_thread_common.h
index 3b3a6996a..f8221a851 100644
--- a/vp9/common/vp9_thread_common.h
+++ b/vp9/common/vp9_thread_common.h
@@ -12,7 +12,7 @@
#define VP9_COMMON_VP9_LOOPFILTER_THREAD_H_
#include "./vpx_config.h"
#include "vp9/common/vp9_loopfilter.h"
-#include "vp9/common/vp9_thread.h"
+#include "vpx_thread/vpx_thread.h"
struct VP9Common;
struct FRAME_COUNTS;