Use vpx prefix for codec independent threading functions
Replace vp9_ prefix with vpx_ for common multi-threading functions. Change-Id: I941a5ead9bfe8213fdad345511d2061b07797b55
This commit is contained in:
parent
3a3b0be09a
commit
04d2e57425
@ -24,27 +24,27 @@ namespace {
|
|||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
class VP9WorkerThreadTest : public ::testing::TestWithParam<bool> {
|
class VPxWorkerThreadTest : public ::testing::TestWithParam<bool> {
|
||||||
protected:
|
protected:
|
||||||
virtual ~VP9WorkerThreadTest() {}
|
virtual ~VPxWorkerThreadTest() {}
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
vp9_get_worker_interface()->init(&worker_);
|
vpx_get_worker_interface()->init(&worker_);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void TearDown() {
|
virtual void TearDown() {
|
||||||
vp9_get_worker_interface()->end(&worker_);
|
vpx_get_worker_interface()->end(&worker_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Run(VP9Worker* worker) {
|
void Run(VPxWorker* worker) {
|
||||||
const bool synchronous = GetParam();
|
const bool synchronous = GetParam();
|
||||||
if (synchronous) {
|
if (synchronous) {
|
||||||
vp9_get_worker_interface()->execute(worker);
|
vpx_get_worker_interface()->execute(worker);
|
||||||
} else {
|
} else {
|
||||||
vp9_get_worker_interface()->launch(worker);
|
vpx_get_worker_interface()->launch(worker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VP9Worker worker_;
|
VPxWorker worker_;
|
||||||
};
|
};
|
||||||
|
|
||||||
int ThreadHook(void* data, void* return_value) {
|
int ThreadHook(void* data, void* return_value) {
|
||||||
@ -53,12 +53,12 @@ int ThreadHook(void* data, void* return_value) {
|
|||||||
return *reinterpret_cast<int*>(return_value);
|
return *reinterpret_cast<int*>(return_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(VP9WorkerThreadTest, HookSuccess) {
|
TEST_P(VPxWorkerThreadTest, HookSuccess) {
|
||||||
// should be a no-op.
|
// should be a no-op.
|
||||||
EXPECT_NE(vp9_get_worker_interface()->sync(&worker_), 0);
|
EXPECT_NE(vpx_get_worker_interface()->sync(&worker_), 0);
|
||||||
|
|
||||||
for (int i = 0; i < 2; ++i) {
|
for (int i = 0; i < 2; ++i) {
|
||||||
EXPECT_NE(vp9_get_worker_interface()->reset(&worker_), 0);
|
EXPECT_NE(vpx_get_worker_interface()->reset(&worker_), 0);
|
||||||
|
|
||||||
int hook_data = 0;
|
int hook_data = 0;
|
||||||
int return_value = 1; // return successfully from the hook
|
int return_value = 1; // return successfully from the hook
|
||||||
@ -67,17 +67,17 @@ TEST_P(VP9WorkerThreadTest, HookSuccess) {
|
|||||||
worker_.data2 = &return_value;
|
worker_.data2 = &return_value;
|
||||||
|
|
||||||
Run(&worker_);
|
Run(&worker_);
|
||||||
EXPECT_NE(vp9_get_worker_interface()->sync(&worker_), 0);
|
EXPECT_NE(vpx_get_worker_interface()->sync(&worker_), 0);
|
||||||
EXPECT_FALSE(worker_.had_error);
|
EXPECT_FALSE(worker_.had_error);
|
||||||
EXPECT_EQ(5, hook_data);
|
EXPECT_EQ(5, hook_data);
|
||||||
|
|
||||||
// should be a no-op.
|
// should be a no-op.
|
||||||
EXPECT_NE(vp9_get_worker_interface()->sync(&worker_), 0);
|
EXPECT_NE(vpx_get_worker_interface()->sync(&worker_), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(VP9WorkerThreadTest, HookFailure) {
|
TEST_P(VPxWorkerThreadTest, HookFailure) {
|
||||||
EXPECT_NE(vp9_get_worker_interface()->reset(&worker_), 0);
|
EXPECT_NE(vpx_get_worker_interface()->reset(&worker_), 0);
|
||||||
|
|
||||||
int hook_data = 0;
|
int hook_data = 0;
|
||||||
int return_value = 0; // return failure from the hook
|
int return_value = 0; // return failure from the hook
|
||||||
@ -86,29 +86,29 @@ TEST_P(VP9WorkerThreadTest, HookFailure) {
|
|||||||
worker_.data2 = &return_value;
|
worker_.data2 = &return_value;
|
||||||
|
|
||||||
Run(&worker_);
|
Run(&worker_);
|
||||||
EXPECT_FALSE(vp9_get_worker_interface()->sync(&worker_));
|
EXPECT_FALSE(vpx_get_worker_interface()->sync(&worker_));
|
||||||
EXPECT_EQ(1, worker_.had_error);
|
EXPECT_EQ(1, worker_.had_error);
|
||||||
|
|
||||||
// Ensure _reset() clears the error and _launch() can be called again.
|
// Ensure _reset() clears the error and _launch() can be called again.
|
||||||
return_value = 1;
|
return_value = 1;
|
||||||
EXPECT_NE(vp9_get_worker_interface()->reset(&worker_), 0);
|
EXPECT_NE(vpx_get_worker_interface()->reset(&worker_), 0);
|
||||||
EXPECT_FALSE(worker_.had_error);
|
EXPECT_FALSE(worker_.had_error);
|
||||||
vp9_get_worker_interface()->launch(&worker_);
|
vpx_get_worker_interface()->launch(&worker_);
|
||||||
EXPECT_NE(vp9_get_worker_interface()->sync(&worker_), 0);
|
EXPECT_NE(vpx_get_worker_interface()->sync(&worker_), 0);
|
||||||
EXPECT_FALSE(worker_.had_error);
|
EXPECT_FALSE(worker_.had_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(VP9WorkerThreadTest, EndWithoutSync) {
|
TEST_P(VPxWorkerThreadTest, EndWithoutSync) {
|
||||||
// Create a large number of threads to increase the chances of detecting a
|
// Create a large number of threads to increase the chances of detecting a
|
||||||
// race. Doing more work in the hook is no guarantee as any race would occur
|
// race. Doing more work in the hook is no guarantee as any race would occur
|
||||||
// post hook execution in the main thread loop driver.
|
// post hook execution in the main thread loop driver.
|
||||||
static const int kNumWorkers = 64;
|
static const int kNumWorkers = 64;
|
||||||
VP9Worker workers[kNumWorkers];
|
VPxWorker workers[kNumWorkers];
|
||||||
int hook_data[kNumWorkers];
|
int hook_data[kNumWorkers];
|
||||||
int return_value[kNumWorkers];
|
int return_value[kNumWorkers];
|
||||||
|
|
||||||
for (int n = 0; n < kNumWorkers; ++n) {
|
for (int n = 0; n < kNumWorkers; ++n) {
|
||||||
vp9_get_worker_interface()->init(&workers[n]);
|
vpx_get_worker_interface()->init(&workers[n]);
|
||||||
return_value[n] = 1; // return successfully from the hook
|
return_value[n] = 1; // return successfully from the hook
|
||||||
workers[n].hook = ThreadHook;
|
workers[n].hook = ThreadHook;
|
||||||
workers[n].data1 = &hook_data[n];
|
workers[n].data1 = &hook_data[n];
|
||||||
@ -117,7 +117,7 @@ TEST_P(VP9WorkerThreadTest, EndWithoutSync) {
|
|||||||
|
|
||||||
for (int i = 0; i < 2; ++i) {
|
for (int i = 0; i < 2; ++i) {
|
||||||
for (int n = 0; n < kNumWorkers; ++n) {
|
for (int n = 0; n < kNumWorkers; ++n) {
|
||||||
EXPECT_NE(vp9_get_worker_interface()->reset(&workers[n]), 0);
|
EXPECT_NE(vpx_get_worker_interface()->reset(&workers[n]), 0);
|
||||||
hook_data[n] = 0;
|
hook_data[n] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,16 +126,16 @@ TEST_P(VP9WorkerThreadTest, EndWithoutSync) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int n = kNumWorkers - 1; n >= 0; --n) {
|
for (int n = kNumWorkers - 1; n >= 0; --n) {
|
||||||
vp9_get_worker_interface()->end(&workers[n]);
|
vpx_get_worker_interface()->end(&workers[n]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(VP9WorkerThreadTest, TestInterfaceAPI) {
|
TEST(VPxWorkerThreadTest, TestInterfaceAPI) {
|
||||||
EXPECT_EQ(0, vp9_set_worker_interface(NULL));
|
EXPECT_EQ(0, vpx_set_worker_interface(NULL));
|
||||||
EXPECT_TRUE(vp9_get_worker_interface() != NULL);
|
EXPECT_TRUE(vpx_get_worker_interface() != NULL);
|
||||||
for (int i = 0; i < 6; ++i) {
|
for (int i = 0; i < 6; ++i) {
|
||||||
VP9WorkerInterface winterface = *vp9_get_worker_interface();
|
VPxWorkerInterface winterface = *vpx_get_worker_interface();
|
||||||
switch (i) {
|
switch (i) {
|
||||||
default:
|
default:
|
||||||
case 0: winterface.init = NULL; break;
|
case 0: winterface.init = NULL; break;
|
||||||
@ -145,7 +145,7 @@ TEST(VP9WorkerThreadTest, TestInterfaceAPI) {
|
|||||||
case 4: winterface.execute = NULL; break;
|
case 4: winterface.execute = NULL; break;
|
||||||
case 5: winterface.end = NULL; break;
|
case 5: winterface.end = NULL; break;
|
||||||
}
|
}
|
||||||
EXPECT_EQ(0, vp9_set_worker_interface(&winterface));
|
EXPECT_EQ(0, vpx_set_worker_interface(&winterface));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,21 +202,21 @@ void DecodeFiles(const FileList files[]) {
|
|||||||
// hang.
|
// hang.
|
||||||
namespace impl {
|
namespace impl {
|
||||||
|
|
||||||
void Init(VP9Worker *const worker) { memset(worker, 0, sizeof(*worker)); }
|
void Init(VPxWorker *const worker) { memset(worker, 0, sizeof(*worker)); }
|
||||||
int Reset(VP9Worker *const /*worker*/) { return 1; }
|
int Reset(VPxWorker *const /*worker*/) { return 1; }
|
||||||
int Sync(VP9Worker *const worker) { return !worker->had_error; }
|
int Sync(VPxWorker *const worker) { return !worker->had_error; }
|
||||||
|
|
||||||
void Execute(VP9Worker *const worker) {
|
void Execute(VPxWorker *const worker) {
|
||||||
worker->had_error |= !worker->hook(worker->data1, worker->data2);
|
worker->had_error |= !worker->hook(worker->data1, worker->data2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Launch(VP9Worker *const worker) { Execute(worker); }
|
void Launch(VPxWorker *const worker) { Execute(worker); }
|
||||||
void End(VP9Worker *const /*worker*/) {}
|
void End(VPxWorker *const /*worker*/) {}
|
||||||
|
|
||||||
} // namespace impl
|
} // namespace impl
|
||||||
|
|
||||||
TEST(VP9WorkerThreadTest, TestSerialInterface) {
|
TEST(VPxWorkerThreadTest, TestSerialInterface) {
|
||||||
static const VP9WorkerInterface serial_interface = {
|
static const VPxWorkerInterface serial_interface = {
|
||||||
impl::Init, impl::Reset, impl::Sync, impl::Launch, impl::Execute, impl::End
|
impl::Init, impl::Reset, impl::Sync, impl::Launch, impl::Execute, impl::End
|
||||||
};
|
};
|
||||||
// TODO(jzern): Avoid using a file that will use the row-based thread
|
// TODO(jzern): Avoid using a file that will use the row-based thread
|
||||||
@ -225,13 +225,13 @@ TEST(VP9WorkerThreadTest, TestSerialInterface) {
|
|||||||
// progress in the row above before proceeding.
|
// progress in the row above before proceeding.
|
||||||
static const char expected_md5[] = "b35a1b707b28e82be025d960aba039bc";
|
static const char expected_md5[] = "b35a1b707b28e82be025d960aba039bc";
|
||||||
static const char filename[] = "vp90-2-03-size-226x226.webm";
|
static const char filename[] = "vp90-2-03-size-226x226.webm";
|
||||||
VP9WorkerInterface default_interface = *vp9_get_worker_interface();
|
VPxWorkerInterface default_interface = *vpx_get_worker_interface();
|
||||||
|
|
||||||
EXPECT_NE(vp9_set_worker_interface(&serial_interface), 0);
|
EXPECT_NE(vpx_set_worker_interface(&serial_interface), 0);
|
||||||
EXPECT_EQ(expected_md5, DecodeFile(filename, 2));
|
EXPECT_EQ(expected_md5, DecodeFile(filename, 2));
|
||||||
|
|
||||||
// Reset the interface.
|
// Reset the interface.
|
||||||
EXPECT_NE(vp9_set_worker_interface(&default_interface), 0);
|
EXPECT_NE(vpx_set_worker_interface(&default_interface), 0);
|
||||||
EXPECT_EQ(expected_md5, DecodeFile(filename, 2));
|
EXPECT_EQ(expected_md5, DecodeFile(filename, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,6 +309,6 @@ TEST(VP9DecodeMultiThreadedTest, Decode3) {
|
|||||||
}
|
}
|
||||||
#endif // CONFIG_WEBM_IO
|
#endif // CONFIG_WEBM_IO
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(Synchronous, VP9WorkerThreadTest, ::testing::Bool());
|
INSTANTIATE_TEST_CASE_P(Synchronous, VPxWorkerThreadTest, ::testing::Bool());
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -80,7 +80,7 @@ typedef struct {
|
|||||||
|
|
||||||
// frame_worker_owner indicates which FrameWorker owns this buffer. NULL means
|
// frame_worker_owner indicates which FrameWorker owns this buffer. NULL means
|
||||||
// that no FrameWorker owns, or is decoding, this buffer.
|
// that no FrameWorker owns, or is decoding, this buffer.
|
||||||
VP9Worker *frame_worker_owner;
|
VPxWorker *frame_worker_owner;
|
||||||
|
|
||||||
// row and col indicate which position frame has been decoded to in real
|
// row and col indicate which position frame has been decoded to in real
|
||||||
// pixel unit. They are reset to -1 when decoding begins and set to INT_MAX
|
// pixel unit. They are reset to -1 when decoding begins and set to INT_MAX
|
||||||
|
@ -157,9 +157,9 @@ static void loop_filter_rows_mt(YV12_BUFFER_CONFIG *frame,
|
|||||||
VP9_COMMON *cm,
|
VP9_COMMON *cm,
|
||||||
struct macroblockd_plane planes[MAX_MB_PLANE],
|
struct macroblockd_plane planes[MAX_MB_PLANE],
|
||||||
int start, int stop, int y_only,
|
int start, int stop, int y_only,
|
||||||
VP9Worker *workers, int nworkers,
|
VPxWorker *workers, int nworkers,
|
||||||
VP9LfSync *lf_sync) {
|
VP9LfSync *lf_sync) {
|
||||||
const VP9WorkerInterface *const winterface = vp9_get_worker_interface();
|
const VPxWorkerInterface *const winterface = vpx_get_worker_interface();
|
||||||
// Number of superblock rows and cols
|
// Number of superblock rows and cols
|
||||||
const int sb_rows = mi_cols_aligned_to_sb(cm->mi_rows) >> MI_BLOCK_SIZE_LOG2;
|
const int sb_rows = mi_cols_aligned_to_sb(cm->mi_rows) >> MI_BLOCK_SIZE_LOG2;
|
||||||
// Decoder may allocate more threads than number of tiles based on user's
|
// Decoder may allocate more threads than number of tiles based on user's
|
||||||
@ -186,10 +186,10 @@ static void loop_filter_rows_mt(YV12_BUFFER_CONFIG *frame,
|
|||||||
// because of contention. If the multithreading code changes in the future
|
// because of contention. If the multithreading code changes in the future
|
||||||
// then the number of workers used by the loopfilter should be revisited.
|
// then the number of workers used by the loopfilter should be revisited.
|
||||||
for (i = 0; i < num_workers; ++i) {
|
for (i = 0; i < num_workers; ++i) {
|
||||||
VP9Worker *const worker = &workers[i];
|
VPxWorker *const worker = &workers[i];
|
||||||
LFWorkerData *const lf_data = &lf_sync->lfdata[i];
|
LFWorkerData *const lf_data = &lf_sync->lfdata[i];
|
||||||
|
|
||||||
worker->hook = (VP9WorkerHook)loop_filter_row_worker;
|
worker->hook = (VPxWorkerHook)loop_filter_row_worker;
|
||||||
worker->data1 = lf_sync;
|
worker->data1 = lf_sync;
|
||||||
worker->data2 = lf_data;
|
worker->data2 = lf_data;
|
||||||
|
|
||||||
@ -218,7 +218,7 @@ void vp9_loop_filter_frame_mt(YV12_BUFFER_CONFIG *frame,
|
|||||||
struct macroblockd_plane planes[MAX_MB_PLANE],
|
struct macroblockd_plane planes[MAX_MB_PLANE],
|
||||||
int frame_filter_level,
|
int frame_filter_level,
|
||||||
int y_only, int partial_frame,
|
int y_only, int partial_frame,
|
||||||
VP9Worker *workers, int num_workers,
|
VPxWorker *workers, int num_workers,
|
||||||
VP9LfSync *lf_sync) {
|
VP9LfSync *lf_sync) {
|
||||||
int start_mi_row, end_mi_row, mi_rows_to_filter;
|
int start_mi_row, end_mi_row, mi_rows_to_filter;
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ void vp9_loop_filter_frame_mt(YV12_BUFFER_CONFIG *frame,
|
|||||||
struct macroblockd_plane planes[MAX_MB_PLANE],
|
struct macroblockd_plane planes[MAX_MB_PLANE],
|
||||||
int frame_filter_level,
|
int frame_filter_level,
|
||||||
int y_only, int partial_frame,
|
int y_only, int partial_frame,
|
||||||
VP9Worker *workers, int num_workers,
|
VPxWorker *workers, int num_workers,
|
||||||
VP9LfSync *lf_sync);
|
VP9LfSync *lf_sync);
|
||||||
|
|
||||||
void vp9_accumulate_frame_counts(struct VP9Common *cm,
|
void vp9_accumulate_frame_counts(struct VP9Common *cm,
|
||||||
|
@ -1259,7 +1259,7 @@ static const uint8_t *decode_tiles(VP9Decoder *pbi,
|
|||||||
const uint8_t *data,
|
const uint8_t *data,
|
||||||
const uint8_t *data_end) {
|
const uint8_t *data_end) {
|
||||||
VP9_COMMON *const cm = &pbi->common;
|
VP9_COMMON *const cm = &pbi->common;
|
||||||
const VP9WorkerInterface *const winterface = vp9_get_worker_interface();
|
const VPxWorkerInterface *const winterface = vpx_get_worker_interface();
|
||||||
const int aligned_cols = mi_cols_aligned_to_sb(cm->mi_cols);
|
const int aligned_cols = mi_cols_aligned_to_sb(cm->mi_cols);
|
||||||
const int tile_cols = 1 << cm->log2_tile_cols;
|
const int tile_cols = 1 << cm->log2_tile_cols;
|
||||||
const int tile_rows = 1 << cm->log2_tile_rows;
|
const int tile_rows = 1 << cm->log2_tile_rows;
|
||||||
@ -1272,7 +1272,7 @@ static const uint8_t *decode_tiles(VP9Decoder *pbi,
|
|||||||
pbi->lf_worker.data1 == NULL) {
|
pbi->lf_worker.data1 == NULL) {
|
||||||
CHECK_MEM_ERROR(cm, pbi->lf_worker.data1,
|
CHECK_MEM_ERROR(cm, pbi->lf_worker.data1,
|
||||||
vpx_memalign(32, sizeof(LFWorkerData)));
|
vpx_memalign(32, sizeof(LFWorkerData)));
|
||||||
pbi->lf_worker.hook = (VP9WorkerHook)vp9_loop_filter_worker;
|
pbi->lf_worker.hook = (VPxWorkerHook)vp9_loop_filter_worker;
|
||||||
if (pbi->max_threads > 1 && !winterface->reset(&pbi->lf_worker)) {
|
if (pbi->max_threads > 1 && !winterface->reset(&pbi->lf_worker)) {
|
||||||
vpx_internal_error(&cm->error, VPX_CODEC_ERROR,
|
vpx_internal_error(&cm->error, VPX_CODEC_ERROR,
|
||||||
"Loop filter thread creation failed");
|
"Loop filter thread creation failed");
|
||||||
@ -1434,7 +1434,7 @@ static const uint8_t *decode_tiles_mt(VP9Decoder *pbi,
|
|||||||
const uint8_t *data,
|
const uint8_t *data,
|
||||||
const uint8_t *data_end) {
|
const uint8_t *data_end) {
|
||||||
VP9_COMMON *const cm = &pbi->common;
|
VP9_COMMON *const cm = &pbi->common;
|
||||||
const VP9WorkerInterface *const winterface = vp9_get_worker_interface();
|
const VPxWorkerInterface *const winterface = vpx_get_worker_interface();
|
||||||
const uint8_t *bit_reader_end = NULL;
|
const uint8_t *bit_reader_end = NULL;
|
||||||
const int aligned_mi_cols = mi_cols_aligned_to_sb(cm->mi_cols);
|
const int aligned_mi_cols = mi_cols_aligned_to_sb(cm->mi_cols);
|
||||||
const int tile_cols = 1 << cm->log2_tile_cols;
|
const int tile_cols = 1 << cm->log2_tile_cols;
|
||||||
@ -1464,7 +1464,7 @@ static const uint8_t *decode_tiles_mt(VP9Decoder *pbi,
|
|||||||
CHECK_MEM_ERROR(cm, pbi->tile_worker_info,
|
CHECK_MEM_ERROR(cm, pbi->tile_worker_info,
|
||||||
vpx_malloc(num_threads * sizeof(*pbi->tile_worker_info)));
|
vpx_malloc(num_threads * sizeof(*pbi->tile_worker_info)));
|
||||||
for (i = 0; i < num_threads; ++i) {
|
for (i = 0; i < num_threads; ++i) {
|
||||||
VP9Worker *const worker = &pbi->tile_workers[i];
|
VPxWorker *const worker = &pbi->tile_workers[i];
|
||||||
++pbi->num_tile_workers;
|
++pbi->num_tile_workers;
|
||||||
|
|
||||||
winterface->init(worker);
|
winterface->init(worker);
|
||||||
@ -1477,9 +1477,9 @@ static const uint8_t *decode_tiles_mt(VP9Decoder *pbi,
|
|||||||
|
|
||||||
// Reset tile decoding hook
|
// Reset tile decoding hook
|
||||||
for (n = 0; n < num_workers; ++n) {
|
for (n = 0; n < num_workers; ++n) {
|
||||||
VP9Worker *const worker = &pbi->tile_workers[n];
|
VPxWorker *const worker = &pbi->tile_workers[n];
|
||||||
winterface->sync(worker);
|
winterface->sync(worker);
|
||||||
worker->hook = (VP9WorkerHook)tile_worker_hook;
|
worker->hook = (VPxWorkerHook)tile_worker_hook;
|
||||||
worker->data1 = &pbi->tile_worker_data[n];
|
worker->data1 = &pbi->tile_worker_data[n];
|
||||||
worker->data2 = &pbi->tile_worker_info[n];
|
worker->data2 = &pbi->tile_worker_info[n];
|
||||||
}
|
}
|
||||||
@ -1529,7 +1529,7 @@ static const uint8_t *decode_tiles_mt(VP9Decoder *pbi,
|
|||||||
while (n < tile_cols) {
|
while (n < tile_cols) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < num_workers && n < tile_cols; ++i) {
|
for (i = 0; i < num_workers && n < tile_cols; ++i) {
|
||||||
VP9Worker *const worker = &pbi->tile_workers[i];
|
VPxWorker *const worker = &pbi->tile_workers[i];
|
||||||
TileWorkerData *const tile_data = (TileWorkerData*)worker->data1;
|
TileWorkerData *const tile_data = (TileWorkerData*)worker->data1;
|
||||||
TileInfo *const tile = (TileInfo*)worker->data2;
|
TileInfo *const tile = (TileInfo*)worker->data2;
|
||||||
TileBuffer *const buf = &tile_buffers[0][n];
|
TileBuffer *const buf = &tile_buffers[0][n];
|
||||||
@ -1561,7 +1561,7 @@ static const uint8_t *decode_tiles_mt(VP9Decoder *pbi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (; i > 0; --i) {
|
for (; i > 0; --i) {
|
||||||
VP9Worker *const worker = &pbi->tile_workers[i - 1];
|
VPxWorker *const worker = &pbi->tile_workers[i - 1];
|
||||||
// TODO(jzern): The tile may have specific error data associated with
|
// TODO(jzern): The tile may have specific error data associated with
|
||||||
// its vpx_internal_error_info which could be propagated to the main info
|
// its vpx_internal_error_info which could be propagated to the main info
|
||||||
// in cm. Additionally once the threads have been synced and an error is
|
// in cm. Additionally once the threads have been synced and an error is
|
||||||
@ -2020,7 +2020,7 @@ void vp9_decode_frame(VP9Decoder *pbi,
|
|||||||
// If encoded in frame parallel mode, frame context is ready after decoding
|
// If encoded in frame parallel mode, frame context is ready after decoding
|
||||||
// the frame header.
|
// the frame header.
|
||||||
if (pbi->frame_parallel_decode && cm->frame_parallel_decoding_mode) {
|
if (pbi->frame_parallel_decode && cm->frame_parallel_decoding_mode) {
|
||||||
VP9Worker *const worker = pbi->frame_worker_owner;
|
VPxWorker *const worker = pbi->frame_worker_owner;
|
||||||
FrameWorkerData *const frame_worker_data = worker->data1;
|
FrameWorkerData *const frame_worker_data = worker->data1;
|
||||||
if (cm->refresh_frame_context) {
|
if (cm->refresh_frame_context) {
|
||||||
context_updated = 1;
|
context_updated = 1;
|
||||||
|
@ -118,7 +118,7 @@ VP9Decoder *vp9_decoder_create(BufferPool *const pool) {
|
|||||||
|
|
||||||
cm->error.setjmp = 0;
|
cm->error.setjmp = 0;
|
||||||
|
|
||||||
vp9_get_worker_interface()->init(&pbi->lf_worker);
|
vpx_get_worker_interface()->init(&pbi->lf_worker);
|
||||||
|
|
||||||
return pbi;
|
return pbi;
|
||||||
}
|
}
|
||||||
@ -126,12 +126,12 @@ VP9Decoder *vp9_decoder_create(BufferPool *const pool) {
|
|||||||
void vp9_decoder_remove(VP9Decoder *pbi) {
|
void vp9_decoder_remove(VP9Decoder *pbi) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
vp9_get_worker_interface()->end(&pbi->lf_worker);
|
vpx_get_worker_interface()->end(&pbi->lf_worker);
|
||||||
vpx_free(pbi->lf_worker.data1);
|
vpx_free(pbi->lf_worker.data1);
|
||||||
vpx_free(pbi->tile_data);
|
vpx_free(pbi->tile_data);
|
||||||
for (i = 0; i < pbi->num_tile_workers; ++i) {
|
for (i = 0; i < pbi->num_tile_workers; ++i) {
|
||||||
VP9Worker *const worker = &pbi->tile_workers[i];
|
VPxWorker *const worker = &pbi->tile_workers[i];
|
||||||
vp9_get_worker_interface()->end(worker);
|
vpx_get_worker_interface()->end(worker);
|
||||||
}
|
}
|
||||||
vpx_free(pbi->tile_worker_data);
|
vpx_free(pbi->tile_worker_data);
|
||||||
vpx_free(pbi->tile_worker_info);
|
vpx_free(pbi->tile_worker_info);
|
||||||
@ -311,7 +311,7 @@ int vp9_receive_compressed_data(VP9Decoder *pbi,
|
|||||||
|
|
||||||
pbi->hold_ref_buf = 0;
|
pbi->hold_ref_buf = 0;
|
||||||
if (pbi->frame_parallel_decode) {
|
if (pbi->frame_parallel_decode) {
|
||||||
VP9Worker *const worker = pbi->frame_worker_owner;
|
VPxWorker *const worker = pbi->frame_worker_owner;
|
||||||
vp9_frameworker_lock_stats(worker);
|
vp9_frameworker_lock_stats(worker);
|
||||||
frame_bufs[cm->new_fb_idx].frame_worker_owner = worker;
|
frame_bufs[cm->new_fb_idx].frame_worker_owner = worker;
|
||||||
// Reset decoding progress.
|
// Reset decoding progress.
|
||||||
@ -325,7 +325,7 @@ int vp9_receive_compressed_data(VP9Decoder *pbi,
|
|||||||
|
|
||||||
|
|
||||||
if (setjmp(cm->error.jmp)) {
|
if (setjmp(cm->error.jmp)) {
|
||||||
const VP9WorkerInterface *const winterface = vp9_get_worker_interface();
|
const VPxWorkerInterface *const winterface = vpx_get_worker_interface();
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
cm->error.setjmp = 0;
|
cm->error.setjmp = 0;
|
||||||
@ -387,7 +387,7 @@ int vp9_receive_compressed_data(VP9Decoder *pbi,
|
|||||||
if (pbi->frame_parallel_decode) {
|
if (pbi->frame_parallel_decode) {
|
||||||
// Need to lock the mutex here as another thread may
|
// Need to lock the mutex here as another thread may
|
||||||
// be accessing this buffer.
|
// be accessing this buffer.
|
||||||
VP9Worker *const worker = pbi->frame_worker_owner;
|
VPxWorker *const worker = pbi->frame_worker_owner;
|
||||||
FrameWorkerData *const frame_worker_data = worker->data1;
|
FrameWorkerData *const frame_worker_data = worker->data1;
|
||||||
vp9_frameworker_lock_stats(worker);
|
vp9_frameworker_lock_stats(worker);
|
||||||
|
|
||||||
|
@ -57,9 +57,9 @@ typedef struct VP9Decoder {
|
|||||||
// the same.
|
// the same.
|
||||||
RefCntBuffer *cur_buf; // Current decoding frame buffer.
|
RefCntBuffer *cur_buf; // Current decoding frame buffer.
|
||||||
|
|
||||||
VP9Worker *frame_worker_owner; // frame_worker that owns this pbi.
|
VPxWorker *frame_worker_owner; // frame_worker that owns this pbi.
|
||||||
VP9Worker lf_worker;
|
VPxWorker lf_worker;
|
||||||
VP9Worker *tile_workers;
|
VPxWorker *tile_workers;
|
||||||
TileWorkerData *tile_worker_data;
|
TileWorkerData *tile_worker_data;
|
||||||
TileInfo *tile_worker_info;
|
TileInfo *tile_worker_info;
|
||||||
int num_tile_workers;
|
int num_tile_workers;
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
// #define DEBUG_THREAD
|
// #define DEBUG_THREAD
|
||||||
|
|
||||||
// TODO(hkuang): Clean up all the #ifdef in this file.
|
// TODO(hkuang): Clean up all the #ifdef in this file.
|
||||||
void vp9_frameworker_lock_stats(VP9Worker *const worker) {
|
void vp9_frameworker_lock_stats(VPxWorker *const worker) {
|
||||||
#if CONFIG_MULTITHREAD
|
#if CONFIG_MULTITHREAD
|
||||||
FrameWorkerData *const worker_data = worker->data1;
|
FrameWorkerData *const worker_data = worker->data1;
|
||||||
pthread_mutex_lock(&worker_data->stats_mutex);
|
pthread_mutex_lock(&worker_data->stats_mutex);
|
||||||
@ -26,7 +26,7 @@ void vp9_frameworker_lock_stats(VP9Worker *const worker) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void vp9_frameworker_unlock_stats(VP9Worker *const worker) {
|
void vp9_frameworker_unlock_stats(VPxWorker *const worker) {
|
||||||
#if CONFIG_MULTITHREAD
|
#if CONFIG_MULTITHREAD
|
||||||
FrameWorkerData *const worker_data = worker->data1;
|
FrameWorkerData *const worker_data = worker->data1;
|
||||||
pthread_mutex_unlock(&worker_data->stats_mutex);
|
pthread_mutex_unlock(&worker_data->stats_mutex);
|
||||||
@ -35,7 +35,7 @@ void vp9_frameworker_unlock_stats(VP9Worker *const worker) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void vp9_frameworker_signal_stats(VP9Worker *const worker) {
|
void vp9_frameworker_signal_stats(VPxWorker *const worker) {
|
||||||
#if CONFIG_MULTITHREAD
|
#if CONFIG_MULTITHREAD
|
||||||
FrameWorkerData *const worker_data = worker->data1;
|
FrameWorkerData *const worker_data = worker->data1;
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ void vp9_frameworker_signal_stats(VP9Worker *const worker) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO(hkuang): Remove worker parameter as it is only used in debug code.
|
// TODO(hkuang): Remove worker parameter as it is only used in debug code.
|
||||||
void vp9_frameworker_wait(VP9Worker *const worker, RefCntBuffer *const ref_buf,
|
void vp9_frameworker_wait(VPxWorker *const worker, RefCntBuffer *const ref_buf,
|
||||||
int row) {
|
int row) {
|
||||||
#if CONFIG_MULTITHREAD
|
#if CONFIG_MULTITHREAD
|
||||||
if (!ref_buf)
|
if (!ref_buf)
|
||||||
@ -74,7 +74,7 @@ void vp9_frameworker_wait(VP9Worker *const worker, RefCntBuffer *const ref_buf,
|
|||||||
{
|
{
|
||||||
// Find the worker thread that owns the reference frame. If the reference
|
// Find the worker thread that owns the reference frame. If the reference
|
||||||
// frame has been fully decoded, it may not have owner.
|
// frame has been fully decoded, it may not have owner.
|
||||||
VP9Worker *const ref_worker = ref_buf->frame_worker_owner;
|
VPxWorker *const ref_worker = ref_buf->frame_worker_owner;
|
||||||
FrameWorkerData *const ref_worker_data =
|
FrameWorkerData *const ref_worker_data =
|
||||||
(FrameWorkerData *)ref_worker->data1;
|
(FrameWorkerData *)ref_worker->data1;
|
||||||
const VP9Decoder *const pbi = ref_worker_data->pbi;
|
const VP9Decoder *const pbi = ref_worker_data->pbi;
|
||||||
@ -114,7 +114,7 @@ void vp9_frameworker_wait(VP9Worker *const worker, RefCntBuffer *const ref_buf,
|
|||||||
|
|
||||||
void vp9_frameworker_broadcast(RefCntBuffer *const buf, int row) {
|
void vp9_frameworker_broadcast(RefCntBuffer *const buf, int row) {
|
||||||
#if CONFIG_MULTITHREAD
|
#if CONFIG_MULTITHREAD
|
||||||
VP9Worker *worker = buf->frame_worker_owner;
|
VPxWorker *worker = buf->frame_worker_owner;
|
||||||
|
|
||||||
#ifdef DEBUG_THREAD
|
#ifdef DEBUG_THREAD
|
||||||
{
|
{
|
||||||
@ -134,8 +134,8 @@ void vp9_frameworker_broadcast(RefCntBuffer *const buf, int row) {
|
|||||||
#endif // CONFIG_MULTITHREAD
|
#endif // CONFIG_MULTITHREAD
|
||||||
}
|
}
|
||||||
|
|
||||||
void vp9_frameworker_copy_context(VP9Worker *const dst_worker,
|
void vp9_frameworker_copy_context(VPxWorker *const dst_worker,
|
||||||
VP9Worker *const src_worker) {
|
VPxWorker *const src_worker) {
|
||||||
#if CONFIG_MULTITHREAD
|
#if CONFIG_MULTITHREAD
|
||||||
FrameWorkerData *const src_worker_data = (FrameWorkerData *)src_worker->data1;
|
FrameWorkerData *const src_worker_data = (FrameWorkerData *)src_worker->data1;
|
||||||
FrameWorkerData *const dst_worker_data = (FrameWorkerData *)dst_worker->data1;
|
FrameWorkerData *const dst_worker_data = (FrameWorkerData *)dst_worker->data1;
|
||||||
|
@ -44,15 +44,15 @@ typedef struct FrameWorkerData {
|
|||||||
int frame_decoded; // Finished decoding current frame.
|
int frame_decoded; // Finished decoding current frame.
|
||||||
} FrameWorkerData;
|
} FrameWorkerData;
|
||||||
|
|
||||||
void vp9_frameworker_lock_stats(VP9Worker *const worker);
|
void vp9_frameworker_lock_stats(VPxWorker *const worker);
|
||||||
void vp9_frameworker_unlock_stats(VP9Worker *const worker);
|
void vp9_frameworker_unlock_stats(VPxWorker *const worker);
|
||||||
void vp9_frameworker_signal_stats(VP9Worker *const worker);
|
void vp9_frameworker_signal_stats(VPxWorker *const worker);
|
||||||
|
|
||||||
// Wait until ref_buf has been decoded to row in real pixel unit.
|
// Wait until ref_buf has been decoded to row in real pixel unit.
|
||||||
// Note: worker may already finish decoding ref_buf and release it in order to
|
// Note: worker may already finish decoding ref_buf and release it in order to
|
||||||
// start decoding next frame. So need to check whether worker is still decoding
|
// start decoding next frame. So need to check whether worker is still decoding
|
||||||
// ref_buf.
|
// ref_buf.
|
||||||
void vp9_frameworker_wait(VP9Worker *const worker, RefCntBuffer *const ref_buf,
|
void vp9_frameworker_wait(VPxWorker *const worker, RefCntBuffer *const ref_buf,
|
||||||
int row);
|
int row);
|
||||||
|
|
||||||
// FrameWorker broadcasts its decoding progress so other workers that are
|
// FrameWorker broadcasts its decoding progress so other workers that are
|
||||||
@ -60,7 +60,7 @@ void vp9_frameworker_wait(VP9Worker *const worker, RefCntBuffer *const ref_buf,
|
|||||||
void vp9_frameworker_broadcast(RefCntBuffer *const buf, int row);
|
void vp9_frameworker_broadcast(RefCntBuffer *const buf, int row);
|
||||||
|
|
||||||
// Copy necessary decoding context from src worker to dst worker.
|
// Copy necessary decoding context from src worker to dst worker.
|
||||||
void vp9_frameworker_copy_context(VP9Worker *const dst_worker,
|
void vp9_frameworker_copy_context(VPxWorker *const dst_worker,
|
||||||
VP9Worker *const src_worker);
|
VPxWorker *const src_worker);
|
||||||
|
|
||||||
#endif // VP9_DECODER_VP9_DTHREAD_H_
|
#endif // VP9_DECODER_VP9_DTHREAD_H_
|
||||||
|
@ -1993,11 +1993,11 @@ void vp9_remove_compressor(VP9_COMP *cpi) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (t = 0; t < cpi->num_workers; ++t) {
|
for (t = 0; t < cpi->num_workers; ++t) {
|
||||||
VP9Worker *const worker = &cpi->workers[t];
|
VPxWorker *const worker = &cpi->workers[t];
|
||||||
EncWorkerData *const thread_data = &cpi->tile_thr_data[t];
|
EncWorkerData *const thread_data = &cpi->tile_thr_data[t];
|
||||||
|
|
||||||
// Deallocate allocated threads.
|
// Deallocate allocated threads.
|
||||||
vp9_get_worker_interface()->end(worker);
|
vpx_get_worker_interface()->end(worker);
|
||||||
|
|
||||||
// Deallocate allocated thread data.
|
// Deallocate allocated thread data.
|
||||||
if (t < cpi->num_workers - 1) {
|
if (t < cpi->num_workers - 1) {
|
||||||
|
@ -496,7 +496,7 @@ typedef struct VP9_COMP {
|
|||||||
|
|
||||||
// Multi-threading
|
// Multi-threading
|
||||||
int num_workers;
|
int num_workers;
|
||||||
VP9Worker *workers;
|
VPxWorker *workers;
|
||||||
struct EncWorkerData *tile_thr_data;
|
struct EncWorkerData *tile_thr_data;
|
||||||
VP9LfSync lf_row_sync;
|
VP9LfSync lf_row_sync;
|
||||||
} VP9_COMP;
|
} VP9_COMP;
|
||||||
|
@ -69,7 +69,7 @@ static int get_max_tile_cols(VP9_COMP *cpi) {
|
|||||||
void vp9_encode_tiles_mt(VP9_COMP *cpi) {
|
void vp9_encode_tiles_mt(VP9_COMP *cpi) {
|
||||||
VP9_COMMON *const cm = &cpi->common;
|
VP9_COMMON *const cm = &cpi->common;
|
||||||
const int tile_cols = 1 << cm->log2_tile_cols;
|
const int tile_cols = 1 << cm->log2_tile_cols;
|
||||||
const VP9WorkerInterface *const winterface = vp9_get_worker_interface();
|
const VPxWorkerInterface *const winterface = vpx_get_worker_interface();
|
||||||
const int num_workers = MIN(cpi->oxcf.max_threads, tile_cols);
|
const int num_workers = MIN(cpi->oxcf.max_threads, tile_cols);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ void vp9_encode_tiles_mt(VP9_COMP *cpi) {
|
|||||||
sizeof(*cpi->tile_thr_data)));
|
sizeof(*cpi->tile_thr_data)));
|
||||||
|
|
||||||
for (i = 0; i < allocated_workers; i++) {
|
for (i = 0; i < allocated_workers; i++) {
|
||||||
VP9Worker *const worker = &cpi->workers[i];
|
VPxWorker *const worker = &cpi->workers[i];
|
||||||
EncWorkerData *thread_data = &cpi->tile_thr_data[i];
|
EncWorkerData *thread_data = &cpi->tile_thr_data[i];
|
||||||
|
|
||||||
++cpi->num_workers;
|
++cpi->num_workers;
|
||||||
@ -132,10 +132,10 @@ void vp9_encode_tiles_mt(VP9_COMP *cpi) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < num_workers; i++) {
|
for (i = 0; i < num_workers; i++) {
|
||||||
VP9Worker *const worker = &cpi->workers[i];
|
VPxWorker *const worker = &cpi->workers[i];
|
||||||
EncWorkerData *thread_data;
|
EncWorkerData *thread_data;
|
||||||
|
|
||||||
worker->hook = (VP9WorkerHook)enc_worker_hook;
|
worker->hook = (VPxWorkerHook)enc_worker_hook;
|
||||||
worker->data1 = &cpi->tile_thr_data[i];
|
worker->data1 = &cpi->tile_thr_data[i];
|
||||||
worker->data2 = NULL;
|
worker->data2 = NULL;
|
||||||
thread_data = (EncWorkerData*)worker->data1;
|
thread_data = (EncWorkerData*)worker->data1;
|
||||||
@ -170,7 +170,7 @@ void vp9_encode_tiles_mt(VP9_COMP *cpi) {
|
|||||||
|
|
||||||
// Encode a frame
|
// Encode a frame
|
||||||
for (i = 0; i < num_workers; i++) {
|
for (i = 0; i < num_workers; i++) {
|
||||||
VP9Worker *const worker = &cpi->workers[i];
|
VPxWorker *const worker = &cpi->workers[i];
|
||||||
EncWorkerData *const thread_data = (EncWorkerData*)worker->data1;
|
EncWorkerData *const thread_data = (EncWorkerData*)worker->data1;
|
||||||
|
|
||||||
// Set the starting tile for each thread.
|
// Set the starting tile for each thread.
|
||||||
@ -184,12 +184,12 @@ void vp9_encode_tiles_mt(VP9_COMP *cpi) {
|
|||||||
|
|
||||||
// Encoding ends.
|
// Encoding ends.
|
||||||
for (i = 0; i < num_workers; i++) {
|
for (i = 0; i < num_workers; i++) {
|
||||||
VP9Worker *const worker = &cpi->workers[i];
|
VPxWorker *const worker = &cpi->workers[i];
|
||||||
winterface->sync(worker);
|
winterface->sync(worker);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < num_workers; i++) {
|
for (i = 0; i < num_workers; i++) {
|
||||||
VP9Worker *const worker = &cpi->workers[i];
|
VPxWorker *const worker = &cpi->workers[i];
|
||||||
EncWorkerData *const thread_data = (EncWorkerData*)worker->data1;
|
EncWorkerData *const thread_data = (EncWorkerData*)worker->data1;
|
||||||
|
|
||||||
// Accumulate counters.
|
// Accumulate counters.
|
||||||
|
@ -59,7 +59,7 @@ struct vpx_codec_alg_priv {
|
|||||||
|
|
||||||
// Frame parallel related.
|
// Frame parallel related.
|
||||||
int frame_parallel_decode; // frame-based threading.
|
int frame_parallel_decode; // frame-based threading.
|
||||||
VP9Worker *frame_workers;
|
VPxWorker *frame_workers;
|
||||||
int num_frame_workers;
|
int num_frame_workers;
|
||||||
int next_submit_worker_id;
|
int next_submit_worker_id;
|
||||||
int last_submit_worker_id;
|
int last_submit_worker_id;
|
||||||
@ -112,10 +112,10 @@ static vpx_codec_err_t decoder_destroy(vpx_codec_alg_priv_t *ctx) {
|
|||||||
if (ctx->frame_workers != NULL) {
|
if (ctx->frame_workers != NULL) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < ctx->num_frame_workers; ++i) {
|
for (i = 0; i < ctx->num_frame_workers; ++i) {
|
||||||
VP9Worker *const worker = &ctx->frame_workers[i];
|
VPxWorker *const worker = &ctx->frame_workers[i];
|
||||||
FrameWorkerData *const frame_worker_data =
|
FrameWorkerData *const frame_worker_data =
|
||||||
(FrameWorkerData *)worker->data1;
|
(FrameWorkerData *)worker->data1;
|
||||||
vp9_get_worker_interface()->end(worker);
|
vpx_get_worker_interface()->end(worker);
|
||||||
vp9_remove_common(&frame_worker_data->pbi->common);
|
vp9_remove_common(&frame_worker_data->pbi->common);
|
||||||
#if CONFIG_VP9_POSTPROC
|
#if CONFIG_VP9_POSTPROC
|
||||||
vp9_free_postproc_buffers(&frame_worker_data->pbi->common);
|
vp9_free_postproc_buffers(&frame_worker_data->pbi->common);
|
||||||
@ -279,7 +279,7 @@ static void init_buffer_callbacks(vpx_codec_alg_priv_t *ctx) {
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ctx->num_frame_workers; ++i) {
|
for (i = 0; i < ctx->num_frame_workers; ++i) {
|
||||||
VP9Worker *const worker = &ctx->frame_workers[i];
|
VPxWorker *const worker = &ctx->frame_workers[i];
|
||||||
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
||||||
VP9_COMMON *const cm = &frame_worker_data->pbi->common;
|
VP9_COMMON *const cm = &frame_worker_data->pbi->common;
|
||||||
BufferPool *const pool = cm->buffer_pool;
|
BufferPool *const pool = cm->buffer_pool;
|
||||||
@ -336,7 +336,7 @@ static int frame_worker_hook(void *arg1, void *arg2) {
|
|||||||
// the compressed data.
|
// the compressed data.
|
||||||
if (frame_worker_data->result != 0 ||
|
if (frame_worker_data->result != 0 ||
|
||||||
frame_worker_data->data + frame_worker_data->data_size - 1 > data) {
|
frame_worker_data->data + frame_worker_data->data_size - 1 > data) {
|
||||||
VP9Worker *const worker = frame_worker_data->pbi->frame_worker_owner;
|
VPxWorker *const worker = frame_worker_data->pbi->frame_worker_owner;
|
||||||
BufferPool *const pool = frame_worker_data->pbi->common.buffer_pool;
|
BufferPool *const pool = frame_worker_data->pbi->common.buffer_pool;
|
||||||
// Signal all the other threads that are waiting for this frame.
|
// Signal all the other threads that are waiting for this frame.
|
||||||
vp9_frameworker_lock_stats(worker);
|
vp9_frameworker_lock_stats(worker);
|
||||||
@ -359,7 +359,7 @@ static int frame_worker_hook(void *arg1, void *arg2) {
|
|||||||
|
|
||||||
static vpx_codec_err_t init_decoder(vpx_codec_alg_priv_t *ctx) {
|
static vpx_codec_err_t init_decoder(vpx_codec_alg_priv_t *ctx) {
|
||||||
int i;
|
int i;
|
||||||
const VP9WorkerInterface *const winterface = vp9_get_worker_interface();
|
const VPxWorkerInterface *const winterface = vpx_get_worker_interface();
|
||||||
|
|
||||||
ctx->last_show_frame = -1;
|
ctx->last_show_frame = -1;
|
||||||
ctx->next_submit_worker_id = 0;
|
ctx->next_submit_worker_id = 0;
|
||||||
@ -387,7 +387,7 @@ static vpx_codec_err_t init_decoder(vpx_codec_alg_priv_t *ctx) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ctx->frame_workers = (VP9Worker *)
|
ctx->frame_workers = (VPxWorker *)
|
||||||
vpx_malloc(ctx->num_frame_workers * sizeof(*ctx->frame_workers));
|
vpx_malloc(ctx->num_frame_workers * sizeof(*ctx->frame_workers));
|
||||||
if (ctx->frame_workers == NULL) {
|
if (ctx->frame_workers == NULL) {
|
||||||
set_error_detail(ctx, "Failed to allocate frame_workers");
|
set_error_detail(ctx, "Failed to allocate frame_workers");
|
||||||
@ -395,7 +395,7 @@ static vpx_codec_err_t init_decoder(vpx_codec_alg_priv_t *ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < ctx->num_frame_workers; ++i) {
|
for (i = 0; i < ctx->num_frame_workers; ++i) {
|
||||||
VP9Worker *const worker = &ctx->frame_workers[i];
|
VPxWorker *const worker = &ctx->frame_workers[i];
|
||||||
FrameWorkerData *frame_worker_data = NULL;
|
FrameWorkerData *frame_worker_data = NULL;
|
||||||
winterface->init(worker);
|
winterface->init(worker);
|
||||||
worker->data1 = vpx_memalign(32, sizeof(FrameWorkerData));
|
worker->data1 = vpx_memalign(32, sizeof(FrameWorkerData));
|
||||||
@ -435,7 +435,7 @@ static vpx_codec_err_t init_decoder(vpx_codec_alg_priv_t *ctx) {
|
|||||||
frame_worker_data->pbi->frame_parallel_decode = ctx->frame_parallel_decode;
|
frame_worker_data->pbi->frame_parallel_decode = ctx->frame_parallel_decode;
|
||||||
frame_worker_data->pbi->common.frame_parallel_decode =
|
frame_worker_data->pbi->common.frame_parallel_decode =
|
||||||
ctx->frame_parallel_decode;
|
ctx->frame_parallel_decode;
|
||||||
worker->hook = (VP9WorkerHook)frame_worker_hook;
|
worker->hook = (VPxWorkerHook)frame_worker_hook;
|
||||||
if (!winterface->reset(worker)) {
|
if (!winterface->reset(worker)) {
|
||||||
set_error_detail(ctx, "Frame Worker thread creation failed");
|
set_error_detail(ctx, "Frame Worker thread creation failed");
|
||||||
return VPX_CODEC_MEM_ERROR;
|
return VPX_CODEC_MEM_ERROR;
|
||||||
@ -464,7 +464,7 @@ static INLINE void check_resync(vpx_codec_alg_priv_t *const ctx,
|
|||||||
static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx,
|
static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx,
|
||||||
const uint8_t **data, unsigned int data_sz,
|
const uint8_t **data, unsigned int data_sz,
|
||||||
void *user_priv, int64_t deadline) {
|
void *user_priv, int64_t deadline) {
|
||||||
const VP9WorkerInterface *const winterface = vp9_get_worker_interface();
|
const VPxWorkerInterface *const winterface = vpx_get_worker_interface();
|
||||||
(void)deadline;
|
(void)deadline;
|
||||||
|
|
||||||
// Determine the stream parameters. Note that we rely on peek_si to
|
// Determine the stream parameters. Note that we rely on peek_si to
|
||||||
@ -483,7 +483,7 @@ static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!ctx->frame_parallel_decode) {
|
if (!ctx->frame_parallel_decode) {
|
||||||
VP9Worker *const worker = ctx->frame_workers;
|
VPxWorker *const worker = ctx->frame_workers;
|
||||||
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
||||||
frame_worker_data->data = *data;
|
frame_worker_data->data = *data;
|
||||||
frame_worker_data->data_size = data_sz;
|
frame_worker_data->data_size = data_sz;
|
||||||
@ -506,7 +506,7 @@ static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx,
|
|||||||
|
|
||||||
check_resync(ctx, frame_worker_data->pbi);
|
check_resync(ctx, frame_worker_data->pbi);
|
||||||
} else {
|
} else {
|
||||||
VP9Worker *const worker = &ctx->frame_workers[ctx->next_submit_worker_id];
|
VPxWorker *const worker = &ctx->frame_workers[ctx->next_submit_worker_id];
|
||||||
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
||||||
// Copy context from last worker thread to next worker thread.
|
// Copy context from last worker thread to next worker thread.
|
||||||
if (ctx->next_submit_worker_id != ctx->last_submit_worker_id)
|
if (ctx->next_submit_worker_id != ctx->last_submit_worker_id)
|
||||||
@ -554,8 +554,8 @@ static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx,
|
|||||||
static void wait_worker_and_cache_frame(vpx_codec_alg_priv_t *ctx) {
|
static void wait_worker_and_cache_frame(vpx_codec_alg_priv_t *ctx) {
|
||||||
YV12_BUFFER_CONFIG sd;
|
YV12_BUFFER_CONFIG sd;
|
||||||
vp9_ppflags_t flags = {0, 0, 0};
|
vp9_ppflags_t flags = {0, 0, 0};
|
||||||
const VP9WorkerInterface *const winterface = vp9_get_worker_interface();
|
const VPxWorkerInterface *const winterface = vpx_get_worker_interface();
|
||||||
VP9Worker *const worker = &ctx->frame_workers[ctx->next_output_worker_id];
|
VPxWorker *const worker = &ctx->frame_workers[ctx->next_output_worker_id];
|
||||||
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
||||||
ctx->next_output_worker_id =
|
ctx->next_output_worker_id =
|
||||||
(ctx->next_output_worker_id + 1) % ctx->num_frame_workers;
|
(ctx->next_output_worker_id + 1) % ctx->num_frame_workers;
|
||||||
@ -746,8 +746,8 @@ static vpx_image_t *decoder_get_frame(vpx_codec_alg_priv_t *ctx,
|
|||||||
do {
|
do {
|
||||||
YV12_BUFFER_CONFIG sd;
|
YV12_BUFFER_CONFIG sd;
|
||||||
vp9_ppflags_t flags = {0, 0, 0};
|
vp9_ppflags_t flags = {0, 0, 0};
|
||||||
const VP9WorkerInterface *const winterface = vp9_get_worker_interface();
|
const VPxWorkerInterface *const winterface = vpx_get_worker_interface();
|
||||||
VP9Worker *const worker =
|
VPxWorker *const worker =
|
||||||
&ctx->frame_workers[ctx->next_output_worker_id];
|
&ctx->frame_workers[ctx->next_output_worker_id];
|
||||||
FrameWorkerData *const frame_worker_data =
|
FrameWorkerData *const frame_worker_data =
|
||||||
(FrameWorkerData *)worker->data1;
|
(FrameWorkerData *)worker->data1;
|
||||||
@ -819,7 +819,7 @@ static vpx_codec_err_t ctrl_set_reference(vpx_codec_alg_priv_t *ctx,
|
|||||||
if (data) {
|
if (data) {
|
||||||
vpx_ref_frame_t *const frame = (vpx_ref_frame_t *)data;
|
vpx_ref_frame_t *const frame = (vpx_ref_frame_t *)data;
|
||||||
YV12_BUFFER_CONFIG sd;
|
YV12_BUFFER_CONFIG sd;
|
||||||
VP9Worker *const worker = ctx->frame_workers;
|
VPxWorker *const worker = ctx->frame_workers;
|
||||||
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
||||||
image2yuvconfig(&frame->img, &sd);
|
image2yuvconfig(&frame->img, &sd);
|
||||||
return vp9_set_reference_dec(&frame_worker_data->pbi->common,
|
return vp9_set_reference_dec(&frame_worker_data->pbi->common,
|
||||||
@ -842,7 +842,7 @@ static vpx_codec_err_t ctrl_copy_reference(vpx_codec_alg_priv_t *ctx,
|
|||||||
if (data) {
|
if (data) {
|
||||||
vpx_ref_frame_t *frame = (vpx_ref_frame_t *) data;
|
vpx_ref_frame_t *frame = (vpx_ref_frame_t *) data;
|
||||||
YV12_BUFFER_CONFIG sd;
|
YV12_BUFFER_CONFIG sd;
|
||||||
VP9Worker *const worker = ctx->frame_workers;
|
VPxWorker *const worker = ctx->frame_workers;
|
||||||
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
||||||
image2yuvconfig(&frame->img, &sd);
|
image2yuvconfig(&frame->img, &sd);
|
||||||
return vp9_copy_reference_dec(frame_worker_data->pbi,
|
return vp9_copy_reference_dec(frame_worker_data->pbi,
|
||||||
@ -864,7 +864,7 @@ static vpx_codec_err_t ctrl_get_reference(vpx_codec_alg_priv_t *ctx,
|
|||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
YV12_BUFFER_CONFIG* fb;
|
YV12_BUFFER_CONFIG* fb;
|
||||||
VP9Worker *const worker = ctx->frame_workers;
|
VPxWorker *const worker = ctx->frame_workers;
|
||||||
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
||||||
fb = get_ref_frame(&frame_worker_data->pbi->common, data->idx);
|
fb = get_ref_frame(&frame_worker_data->pbi->common, data->idx);
|
||||||
if (fb == NULL) return VPX_CODEC_ERROR;
|
if (fb == NULL) return VPX_CODEC_ERROR;
|
||||||
@ -913,7 +913,7 @@ static vpx_codec_err_t ctrl_get_last_ref_updates(vpx_codec_alg_priv_t *ctx,
|
|||||||
|
|
||||||
if (update_info) {
|
if (update_info) {
|
||||||
if (ctx->frame_workers) {
|
if (ctx->frame_workers) {
|
||||||
VP9Worker *const worker = ctx->frame_workers;
|
VPxWorker *const worker = ctx->frame_workers;
|
||||||
FrameWorkerData *const frame_worker_data =
|
FrameWorkerData *const frame_worker_data =
|
||||||
(FrameWorkerData *)worker->data1;
|
(FrameWorkerData *)worker->data1;
|
||||||
*update_info = frame_worker_data->pbi->refresh_frame_flags;
|
*update_info = frame_worker_data->pbi->refresh_frame_flags;
|
||||||
@ -932,7 +932,7 @@ static vpx_codec_err_t ctrl_get_frame_corrupted(vpx_codec_alg_priv_t *ctx,
|
|||||||
|
|
||||||
if (corrupted) {
|
if (corrupted) {
|
||||||
if (ctx->frame_workers) {
|
if (ctx->frame_workers) {
|
||||||
VP9Worker *const worker = ctx->frame_workers;
|
VPxWorker *const worker = ctx->frame_workers;
|
||||||
FrameWorkerData *const frame_worker_data =
|
FrameWorkerData *const frame_worker_data =
|
||||||
(FrameWorkerData *)worker->data1;
|
(FrameWorkerData *)worker->data1;
|
||||||
RefCntBuffer *const frame_bufs =
|
RefCntBuffer *const frame_bufs =
|
||||||
@ -962,7 +962,7 @@ static vpx_codec_err_t ctrl_get_frame_size(vpx_codec_alg_priv_t *ctx,
|
|||||||
|
|
||||||
if (frame_size) {
|
if (frame_size) {
|
||||||
if (ctx->frame_workers) {
|
if (ctx->frame_workers) {
|
||||||
VP9Worker *const worker = ctx->frame_workers;
|
VPxWorker *const worker = ctx->frame_workers;
|
||||||
FrameWorkerData *const frame_worker_data =
|
FrameWorkerData *const frame_worker_data =
|
||||||
(FrameWorkerData *)worker->data1;
|
(FrameWorkerData *)worker->data1;
|
||||||
const VP9_COMMON *const cm = &frame_worker_data->pbi->common;
|
const VP9_COMMON *const cm = &frame_worker_data->pbi->common;
|
||||||
@ -989,7 +989,7 @@ static vpx_codec_err_t ctrl_get_display_size(vpx_codec_alg_priv_t *ctx,
|
|||||||
|
|
||||||
if (display_size) {
|
if (display_size) {
|
||||||
if (ctx->frame_workers) {
|
if (ctx->frame_workers) {
|
||||||
VP9Worker *const worker = ctx->frame_workers;
|
VPxWorker *const worker = ctx->frame_workers;
|
||||||
FrameWorkerData *const frame_worker_data =
|
FrameWorkerData *const frame_worker_data =
|
||||||
(FrameWorkerData *)worker->data1;
|
(FrameWorkerData *)worker->data1;
|
||||||
const VP9_COMMON *const cm = &frame_worker_data->pbi->common;
|
const VP9_COMMON *const cm = &frame_worker_data->pbi->common;
|
||||||
@ -1007,7 +1007,7 @@ static vpx_codec_err_t ctrl_get_display_size(vpx_codec_alg_priv_t *ctx,
|
|||||||
static vpx_codec_err_t ctrl_get_bit_depth(vpx_codec_alg_priv_t *ctx,
|
static vpx_codec_err_t ctrl_get_bit_depth(vpx_codec_alg_priv_t *ctx,
|
||||||
va_list args) {
|
va_list args) {
|
||||||
unsigned int *const bit_depth = va_arg(args, unsigned int *);
|
unsigned int *const bit_depth = va_arg(args, unsigned int *);
|
||||||
VP9Worker *const worker = &ctx->frame_workers[ctx->next_output_worker_id];
|
VPxWorker *const worker = &ctx->frame_workers[ctx->next_output_worker_id];
|
||||||
|
|
||||||
if (bit_depth) {
|
if (bit_depth) {
|
||||||
if (worker) {
|
if (worker) {
|
||||||
@ -1053,7 +1053,7 @@ static vpx_codec_err_t ctrl_set_byte_alignment(vpx_codec_alg_priv_t *ctx,
|
|||||||
|
|
||||||
ctx->byte_alignment = byte_alignment;
|
ctx->byte_alignment = byte_alignment;
|
||||||
if (ctx->frame_workers) {
|
if (ctx->frame_workers) {
|
||||||
VP9Worker *const worker = ctx->frame_workers;
|
VPxWorker *const worker = ctx->frame_workers;
|
||||||
FrameWorkerData *const frame_worker_data =
|
FrameWorkerData *const frame_worker_data =
|
||||||
(FrameWorkerData *)worker->data1;
|
(FrameWorkerData *)worker->data1;
|
||||||
frame_worker_data->pbi->common.byte_alignment = byte_alignment;
|
frame_worker_data->pbi->common.byte_alignment = byte_alignment;
|
||||||
@ -1066,7 +1066,7 @@ static vpx_codec_err_t ctrl_set_skip_loop_filter(vpx_codec_alg_priv_t *ctx,
|
|||||||
ctx->skip_loop_filter = va_arg(args, int);
|
ctx->skip_loop_filter = va_arg(args, int);
|
||||||
|
|
||||||
if (ctx->frame_workers) {
|
if (ctx->frame_workers) {
|
||||||
VP9Worker *const worker = ctx->frame_workers;
|
VPxWorker *const worker = ctx->frame_workers;
|
||||||
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
||||||
frame_worker_data->pbi->common.skip_loop_filter = ctx->skip_loop_filter;
|
frame_worker_data->pbi->common.skip_loop_filter = ctx->skip_loop_filter;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#if CONFIG_MULTITHREAD
|
#if CONFIG_MULTITHREAD
|
||||||
|
|
||||||
struct VP9WorkerImpl {
|
struct VPxWorkerImpl {
|
||||||
pthread_mutex_t mutex_;
|
pthread_mutex_t mutex_;
|
||||||
pthread_cond_t condition_;
|
pthread_cond_t condition_;
|
||||||
pthread_t thread_;
|
pthread_t thread_;
|
||||||
@ -28,10 +28,10 @@ struct VP9WorkerImpl {
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
static void execute(VP9Worker *const worker); // Forward declaration.
|
static void execute(VPxWorker *const worker); // Forward declaration.
|
||||||
|
|
||||||
static THREADFN thread_loop(void *ptr) {
|
static THREADFN thread_loop(void *ptr) {
|
||||||
VP9Worker *const worker = (VP9Worker*)ptr;
|
VPxWorker *const worker = (VPxWorker*)ptr;
|
||||||
int done = 0;
|
int done = 0;
|
||||||
while (!done) {
|
while (!done) {
|
||||||
pthread_mutex_lock(&worker->impl_->mutex_);
|
pthread_mutex_lock(&worker->impl_->mutex_);
|
||||||
@ -52,8 +52,8 @@ static THREADFN thread_loop(void *ptr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// main thread state control
|
// main thread state control
|
||||||
static void change_state(VP9Worker *const worker,
|
static void change_state(VPxWorker *const worker,
|
||||||
VP9WorkerStatus new_status) {
|
VPxWorkerStatus new_status) {
|
||||||
// No-op when attempting to change state on a thread that didn't come up.
|
// 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
|
// Checking status_ without acquiring the lock first would result in a data
|
||||||
// race.
|
// race.
|
||||||
@ -78,12 +78,12 @@ static void change_state(VP9Worker *const worker,
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
static void init(VP9Worker *const worker) {
|
static void init(VPxWorker *const worker) {
|
||||||
memset(worker, 0, sizeof(*worker));
|
memset(worker, 0, sizeof(*worker));
|
||||||
worker->status_ = NOT_OK;
|
worker->status_ = NOT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sync(VP9Worker *const worker) {
|
static int sync(VPxWorker *const worker) {
|
||||||
#if CONFIG_MULTITHREAD
|
#if CONFIG_MULTITHREAD
|
||||||
change_state(worker, OK);
|
change_state(worker, OK);
|
||||||
#endif
|
#endif
|
||||||
@ -91,12 +91,12 @@ static int sync(VP9Worker *const worker) {
|
|||||||
return !worker->had_error;
|
return !worker->had_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int reset(VP9Worker *const worker) {
|
static int reset(VPxWorker *const worker) {
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
worker->had_error = 0;
|
worker->had_error = 0;
|
||||||
if (worker->status_ < OK) {
|
if (worker->status_ < OK) {
|
||||||
#if CONFIG_MULTITHREAD
|
#if CONFIG_MULTITHREAD
|
||||||
worker->impl_ = (VP9WorkerImpl*)vpx_calloc(1, sizeof(*worker->impl_));
|
worker->impl_ = (VPxWorkerImpl*)vpx_calloc(1, sizeof(*worker->impl_));
|
||||||
if (worker->impl_ == NULL) {
|
if (worker->impl_ == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -129,13 +129,13 @@ static int reset(VP9Worker *const worker) {
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void execute(VP9Worker *const worker) {
|
static void execute(VPxWorker *const worker) {
|
||||||
if (worker->hook != NULL) {
|
if (worker->hook != NULL) {
|
||||||
worker->had_error |= !worker->hook(worker->data1, worker->data2);
|
worker->had_error |= !worker->hook(worker->data1, worker->data2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void launch(VP9Worker *const worker) {
|
static void launch(VPxWorker *const worker) {
|
||||||
#if CONFIG_MULTITHREAD
|
#if CONFIG_MULTITHREAD
|
||||||
change_state(worker, WORK);
|
change_state(worker, WORK);
|
||||||
#else
|
#else
|
||||||
@ -143,7 +143,7 @@ static void launch(VP9Worker *const worker) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void end(VP9Worker *const worker) {
|
static void end(VPxWorker *const worker) {
|
||||||
#if CONFIG_MULTITHREAD
|
#if CONFIG_MULTITHREAD
|
||||||
if (worker->impl_ != NULL) {
|
if (worker->impl_ != NULL) {
|
||||||
change_state(worker, NOT_OK);
|
change_state(worker, NOT_OK);
|
||||||
@ -162,11 +162,11 @@ static void end(VP9Worker *const worker) {
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
static VP9WorkerInterface g_worker_interface = {
|
static VPxWorkerInterface g_worker_interface = {
|
||||||
init, reset, sync, launch, execute, end
|
init, reset, sync, launch, execute, end
|
||||||
};
|
};
|
||||||
|
|
||||||
int vp9_set_worker_interface(const VP9WorkerInterface* const winterface) {
|
int vpx_set_worker_interface(const VPxWorkerInterface* const winterface) {
|
||||||
if (winterface == NULL ||
|
if (winterface == NULL ||
|
||||||
winterface->init == NULL || winterface->reset == NULL ||
|
winterface->init == NULL || winterface->reset == NULL ||
|
||||||
winterface->sync == NULL || winterface->launch == NULL ||
|
winterface->sync == NULL || winterface->launch == NULL ||
|
||||||
@ -177,7 +177,7 @@ int vp9_set_worker_interface(const VP9WorkerInterface* const winterface) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const VP9WorkerInterface *vp9_get_worker_interface(void) {
|
const VPxWorkerInterface *vpx_get_worker_interface(void) {
|
||||||
return &g_worker_interface;
|
return &g_worker_interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
// http://git.chromium.org/webm/libwebp.git
|
// http://git.chromium.org/webm/libwebp.git
|
||||||
// 100644 blob 7bd451b124ae3b81596abfbcc823e3cb129d3a38 src/utils/thread.h
|
// 100644 blob 7bd451b124ae3b81596abfbcc823e3cb129d3a38 src/utils/thread.h
|
||||||
|
|
||||||
#ifndef VP9_DECODER_VP9_THREAD_H_
|
#ifndef VPX_THREAD_H_
|
||||||
#define VP9_DECODER_VP9_THREAD_H_
|
#define VPX_THREAD_H_
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
#include "./vpx_config.h"
|
||||||
|
|
||||||
@ -160,59 +160,59 @@ typedef enum {
|
|||||||
NOT_OK = 0, // object is unusable
|
NOT_OK = 0, // object is unusable
|
||||||
OK, // ready to work
|
OK, // ready to work
|
||||||
WORK // busy finishing the current task
|
WORK // busy finishing the current task
|
||||||
} VP9WorkerStatus;
|
} VPxWorkerStatus;
|
||||||
|
|
||||||
// Function to be called by the worker thread. Takes two opaque pointers as
|
// 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.
|
// arguments (data1 and data2), and should return false in case of error.
|
||||||
typedef int (*VP9WorkerHook)(void*, void*);
|
typedef int (*VPxWorkerHook)(void*, void*);
|
||||||
|
|
||||||
// Platform-dependent implementation details for the worker.
|
// Platform-dependent implementation details for the worker.
|
||||||
typedef struct VP9WorkerImpl VP9WorkerImpl;
|
typedef struct VPxWorkerImpl VPxWorkerImpl;
|
||||||
|
|
||||||
// Synchronization object used to launch job in the worker thread
|
// Synchronization object used to launch job in the worker thread
|
||||||
typedef struct {
|
typedef struct {
|
||||||
VP9WorkerImpl *impl_;
|
VPxWorkerImpl *impl_;
|
||||||
VP9WorkerStatus status_;
|
VPxWorkerStatus status_;
|
||||||
VP9WorkerHook hook; // hook to call
|
VPxWorkerHook hook; // hook to call
|
||||||
void *data1; // first argument passed to 'hook'
|
void *data1; // first argument passed to 'hook'
|
||||||
void *data2; // second argument passed to 'hook'
|
void *data2; // second argument passed to 'hook'
|
||||||
int had_error; // return value of the last call to 'hook'
|
int had_error; // return value of the last call to 'hook'
|
||||||
} VP9Worker;
|
} VPxWorker;
|
||||||
|
|
||||||
// The interface for all thread-worker related functions. All these functions
|
// The interface for all thread-worker related functions. All these functions
|
||||||
// must be implemented.
|
// must be implemented.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// Must be called first, before any other method.
|
// Must be called first, before any other method.
|
||||||
void (*init)(VP9Worker *const worker);
|
void (*init)(VPxWorker *const worker);
|
||||||
// Must be called to initialize the object and spawn the thread. Re-entrant.
|
// Must be called to initialize the object and spawn the thread. Re-entrant.
|
||||||
// Will potentially launch the thread. Returns false in case of error.
|
// Will potentially launch the thread. Returns false in case of error.
|
||||||
int (*reset)(VP9Worker *const worker);
|
int (*reset)(VPxWorker *const worker);
|
||||||
// Makes sure the previous work is finished. Returns true if worker->had_error
|
// 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.
|
// was not set and no error condition was triggered by the working thread.
|
||||||
int (*sync)(VP9Worker *const worker);
|
int (*sync)(VPxWorker *const worker);
|
||||||
// Triggers the thread to call hook() with data1 and data2 arguments. These
|
// 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
|
// 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().
|
// function, but not be changed afterward until the next call to Sync().
|
||||||
void (*launch)(VP9Worker *const worker);
|
void (*launch)(VPxWorker *const worker);
|
||||||
// This function is similar to launch() except that it calls the
|
// This function is similar to launch() except that it calls the
|
||||||
// hook directly instead of using a thread. Convenient to bypass the thread
|
// hook directly instead of using a thread. Convenient to bypass the thread
|
||||||
// mechanism while still using the VP9Worker structs. sync() must
|
// mechanism while still using the VPxWorker structs. sync() must
|
||||||
// still be called afterward (for error reporting).
|
// still be called afterward (for error reporting).
|
||||||
void (*execute)(VP9Worker *const worker);
|
void (*execute)(VPxWorker *const worker);
|
||||||
// Kill the thread and terminate the object. To use the object again, one
|
// Kill the thread and terminate the object. To use the object again, one
|
||||||
// must call reset() again.
|
// must call reset() again.
|
||||||
void (*end)(VP9Worker *const worker);
|
void (*end)(VPxWorker *const worker);
|
||||||
} VP9WorkerInterface;
|
} VPxWorkerInterface;
|
||||||
|
|
||||||
// Install a new set of threading functions, overriding the defaults. This
|
// 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
|
// 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
|
// 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
|
// 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.
|
// not thread-safe. Return false in case of invalid pointer or methods.
|
||||||
int vp9_set_worker_interface(const VP9WorkerInterface *const winterface);
|
int vpx_set_worker_interface(const VPxWorkerInterface *const winterface);
|
||||||
|
|
||||||
// Retrieve the currently set thread worker interface.
|
// Retrieve the currently set thread worker interface.
|
||||||
const VP9WorkerInterface *vp9_get_worker_interface(void);
|
const VPxWorkerInterface *vpx_get_worker_interface(void);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -220,4 +220,4 @@ const VP9WorkerInterface *vp9_get_worker_interface(void);
|
|||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // VP9_DECODER_VP9_THREAD_H_
|
#endif // VPX_THREAD_H_
|
||||||
|
Loading…
x
Reference in New Issue
Block a user