Merge changes from topic 'rm-dec-frame-parallel'
* changes: vp9: remove FrameWorkerData & vp9_dthread.h vp9: remove (un)lock_buffer_pool
This commit is contained in:
@@ -99,9 +99,7 @@ class VpxEncoderParmsGetToDecoder
|
|||||||
vpx_codec_ctx_t *const vp9_decoder = decoder->GetDecoder();
|
vpx_codec_ctx_t *const vp9_decoder = decoder->GetDecoder();
|
||||||
vpx_codec_alg_priv_t *const priv =
|
vpx_codec_alg_priv_t *const priv =
|
||||||
reinterpret_cast<vpx_codec_alg_priv_t *>(vp9_decoder->priv);
|
reinterpret_cast<vpx_codec_alg_priv_t *>(vp9_decoder->priv);
|
||||||
FrameWorkerData *const worker_data =
|
VP9_COMMON *const common = &priv->pbi->common;
|
||||||
reinterpret_cast<FrameWorkerData *>(priv->frame_workers[0].data1);
|
|
||||||
VP9_COMMON *const common = &worker_data->pbi->common;
|
|
||||||
|
|
||||||
if (encode_parms.lossless) {
|
if (encode_parms.lossless) {
|
||||||
EXPECT_EQ(0, common->base_qindex);
|
EXPECT_EQ(0, common->base_qindex);
|
||||||
|
|||||||
@@ -17,24 +17,6 @@
|
|||||||
#include "vp9/common/vp9_entropymv.h"
|
#include "vp9/common/vp9_entropymv.h"
|
||||||
#include "vp9/common/vp9_onyxc_int.h"
|
#include "vp9/common/vp9_onyxc_int.h"
|
||||||
|
|
||||||
// TODO(hkuang): Don't need to lock the whole pool after implementing atomic
|
|
||||||
// frame reference count.
|
|
||||||
void lock_buffer_pool(BufferPool *const pool) {
|
|
||||||
#if CONFIG_MULTITHREAD
|
|
||||||
pthread_mutex_lock(&pool->pool_mutex);
|
|
||||||
#else
|
|
||||||
(void)pool;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void unlock_buffer_pool(BufferPool *const pool) {
|
|
||||||
#if CONFIG_MULTITHREAD
|
|
||||||
pthread_mutex_unlock(&pool->pool_mutex);
|
|
||||||
#else
|
|
||||||
(void)pool;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void vp9_set_mb_mi(VP9_COMMON *cm, int width, int height) {
|
void vp9_set_mb_mi(VP9_COMMON *cm, int width, int height) {
|
||||||
const int aligned_width = ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2);
|
const int aligned_width = ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2);
|
||||||
const int aligned_height = ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2);
|
const int aligned_height = ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2);
|
||||||
@@ -172,6 +154,9 @@ fail:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void vp9_remove_common(VP9_COMMON *cm) {
|
void vp9_remove_common(VP9_COMMON *cm) {
|
||||||
|
#if CONFIG_VP9_POSTPROC
|
||||||
|
vp9_free_postproc_buffers(cm);
|
||||||
|
#endif
|
||||||
vp9_free_context_buffers(cm);
|
vp9_free_context_buffers(cm);
|
||||||
|
|
||||||
vpx_free(cm->fc);
|
vpx_free(cm->fc);
|
||||||
|
|||||||
@@ -74,13 +74,6 @@ typedef struct {
|
|||||||
} RefCntBuffer;
|
} RefCntBuffer;
|
||||||
|
|
||||||
typedef struct BufferPool {
|
typedef struct BufferPool {
|
||||||
// Protect BufferPool from being accessed by several FrameWorkers at
|
|
||||||
// the same time during frame parallel decode.
|
|
||||||
// TODO(hkuang): Try to use atomic variable instead of locking the whole pool.
|
|
||||||
#if CONFIG_MULTITHREAD
|
|
||||||
pthread_mutex_t pool_mutex;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Private data associated with the frame buffer callbacks.
|
// Private data associated with the frame buffer callbacks.
|
||||||
void *cb_priv;
|
void *cb_priv;
|
||||||
|
|
||||||
@@ -264,11 +257,6 @@ typedef struct VP9Common {
|
|||||||
int above_context_alloc_cols;
|
int above_context_alloc_cols;
|
||||||
} VP9_COMMON;
|
} VP9_COMMON;
|
||||||
|
|
||||||
// TODO(hkuang): Don't need to lock the whole pool after implementing atomic
|
|
||||||
// frame reference count.
|
|
||||||
void lock_buffer_pool(BufferPool *const pool);
|
|
||||||
void unlock_buffer_pool(BufferPool *const pool);
|
|
||||||
|
|
||||||
static INLINE YV12_BUFFER_CONFIG *get_ref_frame(VP9_COMMON *cm, int index) {
|
static INLINE YV12_BUFFER_CONFIG *get_ref_frame(VP9_COMMON *cm, int index) {
|
||||||
if (index < 0 || index >= REF_FRAMES) return NULL;
|
if (index < 0 || index >= REF_FRAMES) return NULL;
|
||||||
if (cm->ref_frame_map[index] < 0) return NULL;
|
if (cm->ref_frame_map[index] < 0) return NULL;
|
||||||
@@ -284,7 +272,6 @@ static INLINE int get_free_fb(VP9_COMMON *cm) {
|
|||||||
RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
|
RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
lock_buffer_pool(cm->buffer_pool);
|
|
||||||
for (i = 0; i < FRAME_BUFFERS; ++i)
|
for (i = 0; i < FRAME_BUFFERS; ++i)
|
||||||
if (frame_bufs[i].ref_count == 0) break;
|
if (frame_bufs[i].ref_count == 0) break;
|
||||||
|
|
||||||
@@ -295,7 +282,6 @@ static INLINE int get_free_fb(VP9_COMMON *cm) {
|
|||||||
i = INVALID_IDX;
|
i = INVALID_IDX;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_buffer_pool(cm->buffer_pool);
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1171,7 +1171,6 @@ static void setup_frame_size(VP9_COMMON *cm, struct vpx_read_bit_buffer *rb) {
|
|||||||
resize_context_buffers(cm, width, height);
|
resize_context_buffers(cm, width, height);
|
||||||
setup_render_size(cm, rb);
|
setup_render_size(cm, rb);
|
||||||
|
|
||||||
lock_buffer_pool(pool);
|
|
||||||
if (vpx_realloc_frame_buffer(
|
if (vpx_realloc_frame_buffer(
|
||||||
get_frame_new_buffer(cm), cm->width, cm->height, cm->subsampling_x,
|
get_frame_new_buffer(cm), cm->width, cm->height, cm->subsampling_x,
|
||||||
cm->subsampling_y,
|
cm->subsampling_y,
|
||||||
@@ -1181,11 +1180,9 @@ static void setup_frame_size(VP9_COMMON *cm, struct vpx_read_bit_buffer *rb) {
|
|||||||
VP9_DEC_BORDER_IN_PIXELS, cm->byte_alignment,
|
VP9_DEC_BORDER_IN_PIXELS, cm->byte_alignment,
|
||||||
&pool->frame_bufs[cm->new_fb_idx].raw_frame_buffer, pool->get_fb_cb,
|
&pool->frame_bufs[cm->new_fb_idx].raw_frame_buffer, pool->get_fb_cb,
|
||||||
pool->cb_priv)) {
|
pool->cb_priv)) {
|
||||||
unlock_buffer_pool(pool);
|
|
||||||
vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
|
vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
|
||||||
"Failed to allocate frame buffer");
|
"Failed to allocate frame buffer");
|
||||||
}
|
}
|
||||||
unlock_buffer_pool(pool);
|
|
||||||
|
|
||||||
pool->frame_bufs[cm->new_fb_idx].buf.subsampling_x = cm->subsampling_x;
|
pool->frame_bufs[cm->new_fb_idx].buf.subsampling_x = cm->subsampling_x;
|
||||||
pool->frame_bufs[cm->new_fb_idx].buf.subsampling_y = cm->subsampling_y;
|
pool->frame_bufs[cm->new_fb_idx].buf.subsampling_y = cm->subsampling_y;
|
||||||
@@ -1257,7 +1254,6 @@ static void setup_frame_size_with_refs(VP9_COMMON *cm,
|
|||||||
resize_context_buffers(cm, width, height);
|
resize_context_buffers(cm, width, height);
|
||||||
setup_render_size(cm, rb);
|
setup_render_size(cm, rb);
|
||||||
|
|
||||||
lock_buffer_pool(pool);
|
|
||||||
if (vpx_realloc_frame_buffer(
|
if (vpx_realloc_frame_buffer(
|
||||||
get_frame_new_buffer(cm), cm->width, cm->height, cm->subsampling_x,
|
get_frame_new_buffer(cm), cm->width, cm->height, cm->subsampling_x,
|
||||||
cm->subsampling_y,
|
cm->subsampling_y,
|
||||||
@@ -1267,11 +1263,9 @@ static void setup_frame_size_with_refs(VP9_COMMON *cm,
|
|||||||
VP9_DEC_BORDER_IN_PIXELS, cm->byte_alignment,
|
VP9_DEC_BORDER_IN_PIXELS, cm->byte_alignment,
|
||||||
&pool->frame_bufs[cm->new_fb_idx].raw_frame_buffer, pool->get_fb_cb,
|
&pool->frame_bufs[cm->new_fb_idx].raw_frame_buffer, pool->get_fb_cb,
|
||||||
pool->cb_priv)) {
|
pool->cb_priv)) {
|
||||||
unlock_buffer_pool(pool);
|
|
||||||
vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
|
vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
|
||||||
"Failed to allocate frame buffer");
|
"Failed to allocate frame buffer");
|
||||||
}
|
}
|
||||||
unlock_buffer_pool(pool);
|
|
||||||
|
|
||||||
pool->frame_bufs[cm->new_fb_idx].buf.subsampling_x = cm->subsampling_x;
|
pool->frame_bufs[cm->new_fb_idx].buf.subsampling_x = cm->subsampling_x;
|
||||||
pool->frame_bufs[cm->new_fb_idx].buf.subsampling_y = cm->subsampling_y;
|
pool->frame_bufs[cm->new_fb_idx].buf.subsampling_y = cm->subsampling_y;
|
||||||
@@ -1756,16 +1750,13 @@ static size_t read_uncompressed_header(VP9Decoder *pbi,
|
|||||||
if (cm->show_existing_frame) {
|
if (cm->show_existing_frame) {
|
||||||
// Show an existing frame directly.
|
// Show an existing frame directly.
|
||||||
const int frame_to_show = cm->ref_frame_map[vpx_rb_read_literal(rb, 3)];
|
const int frame_to_show = cm->ref_frame_map[vpx_rb_read_literal(rb, 3)];
|
||||||
lock_buffer_pool(pool);
|
|
||||||
if (frame_to_show < 0 || frame_bufs[frame_to_show].ref_count < 1) {
|
if (frame_to_show < 0 || frame_bufs[frame_to_show].ref_count < 1) {
|
||||||
unlock_buffer_pool(pool);
|
|
||||||
vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
|
vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
|
||||||
"Buffer %d does not contain a decoded frame",
|
"Buffer %d does not contain a decoded frame",
|
||||||
frame_to_show);
|
frame_to_show);
|
||||||
}
|
}
|
||||||
|
|
||||||
ref_cnt_fb(frame_bufs, &cm->new_fb_idx, frame_to_show);
|
ref_cnt_fb(frame_bufs, &cm->new_fb_idx, frame_to_show);
|
||||||
unlock_buffer_pool(pool);
|
|
||||||
pbi->refresh_frame_flags = 0;
|
pbi->refresh_frame_flags = 0;
|
||||||
cm->lf.filter_level = 0;
|
cm->lf.filter_level = 0;
|
||||||
cm->show_frame = 1;
|
cm->show_frame = 1;
|
||||||
@@ -1886,7 +1877,6 @@ static size_t read_uncompressed_header(VP9Decoder *pbi,
|
|||||||
cm->frame_context_idx = vpx_rb_read_literal(rb, FRAME_CONTEXTS_LOG2);
|
cm->frame_context_idx = vpx_rb_read_literal(rb, FRAME_CONTEXTS_LOG2);
|
||||||
|
|
||||||
// Generate next_ref_frame_map.
|
// Generate next_ref_frame_map.
|
||||||
lock_buffer_pool(pool);
|
|
||||||
for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) {
|
for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) {
|
||||||
if (mask & 1) {
|
if (mask & 1) {
|
||||||
cm->next_ref_frame_map[ref_index] = cm->new_fb_idx;
|
cm->next_ref_frame_map[ref_index] = cm->new_fb_idx;
|
||||||
@@ -1906,7 +1896,6 @@ static size_t read_uncompressed_header(VP9Decoder *pbi,
|
|||||||
if (cm->ref_frame_map[ref_index] >= 0)
|
if (cm->ref_frame_map[ref_index] >= 0)
|
||||||
++frame_bufs[cm->ref_frame_map[ref_index]].ref_count;
|
++frame_bufs[cm->ref_frame_map[ref_index]].ref_count;
|
||||||
}
|
}
|
||||||
unlock_buffer_pool(pool);
|
|
||||||
pbi->hold_ref_buf = 1;
|
pbi->hold_ref_buf = 1;
|
||||||
|
|
||||||
if (frame_is_intra_only(cm) || cm->error_resilient_mode)
|
if (frame_is_intra_only(cm) || cm->error_resilient_mode)
|
||||||
|
|||||||
@@ -139,6 +139,7 @@ void vp9_decoder_remove(VP9Decoder *pbi) {
|
|||||||
vp9_loop_filter_dealloc(&pbi->lf_row_sync);
|
vp9_loop_filter_dealloc(&pbi->lf_row_sync);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vp9_remove_common(&pbi->common);
|
||||||
vpx_free(pbi);
|
vpx_free(pbi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,7 +231,6 @@ static void swap_frame_buffers(VP9Decoder *pbi) {
|
|||||||
BufferPool *const pool = cm->buffer_pool;
|
BufferPool *const pool = cm->buffer_pool;
|
||||||
RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
|
RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
|
||||||
|
|
||||||
lock_buffer_pool(pool);
|
|
||||||
for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) {
|
for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) {
|
||||||
const int old_idx = cm->ref_frame_map[ref_index];
|
const int old_idx = cm->ref_frame_map[ref_index];
|
||||||
// Current thread releases the holding of reference frame.
|
// Current thread releases the holding of reference frame.
|
||||||
@@ -250,13 +250,10 @@ static void swap_frame_buffers(VP9Decoder *pbi) {
|
|||||||
decrease_ref_count(old_idx, frame_bufs, pool);
|
decrease_ref_count(old_idx, frame_bufs, pool);
|
||||||
cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index];
|
cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index];
|
||||||
}
|
}
|
||||||
unlock_buffer_pool(pool);
|
|
||||||
pbi->hold_ref_buf = 0;
|
pbi->hold_ref_buf = 0;
|
||||||
cm->frame_to_show = get_frame_new_buffer(cm);
|
cm->frame_to_show = get_frame_new_buffer(cm);
|
||||||
|
|
||||||
lock_buffer_pool(pool);
|
|
||||||
--frame_bufs[cm->new_fb_idx].ref_count;
|
--frame_bufs[cm->new_fb_idx].ref_count;
|
||||||
unlock_buffer_pool(pool);
|
|
||||||
|
|
||||||
// Invalidate these references until the next frame starts.
|
// Invalidate these references until the next frame starts.
|
||||||
for (ref_index = 0; ref_index < 3; ref_index++)
|
for (ref_index = 0; ref_index < 3; ref_index++)
|
||||||
@@ -321,7 +318,6 @@ int vp9_receive_compressed_data(VP9Decoder *pbi, size_t size,
|
|||||||
winterface->sync(&pbi->tile_workers[i]);
|
winterface->sync(&pbi->tile_workers[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock_buffer_pool(pool);
|
|
||||||
// Release all the reference buffers if worker thread is holding them.
|
// Release all the reference buffers if worker thread is holding them.
|
||||||
if (pbi->hold_ref_buf == 1) {
|
if (pbi->hold_ref_buf == 1) {
|
||||||
int ref_index = 0, mask;
|
int ref_index = 0, mask;
|
||||||
@@ -346,7 +342,6 @@ int vp9_receive_compressed_data(VP9Decoder *pbi, size_t size,
|
|||||||
}
|
}
|
||||||
// Release current frame.
|
// Release current frame.
|
||||||
decrease_ref_count(cm->new_fb_idx, frame_bufs, pool);
|
decrease_ref_count(cm->new_fb_idx, frame_bufs, pool);
|
||||||
unlock_buffer_pool(pool);
|
|
||||||
|
|
||||||
vpx_clear_system_state();
|
vpx_clear_system_state();
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
#include "vp9/common/vp9_thread_common.h"
|
#include "vp9/common/vp9_thread_common.h"
|
||||||
#include "vp9/common/vp9_onyxc_int.h"
|
#include "vp9/common/vp9_onyxc_int.h"
|
||||||
#include "vp9/common/vp9_ppflags.h"
|
#include "vp9/common/vp9_ppflags.h"
|
||||||
#include "vp9/decoder/vp9_dthread.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef VP9_DECODER_VP9_DTHREAD_H_
|
|
||||||
#define VP9_DECODER_VP9_DTHREAD_H_
|
|
||||||
|
|
||||||
#include "./vpx_config.h"
|
|
||||||
#include "vpx_util/vpx_thread.h"
|
|
||||||
#include "vpx/internal/vpx_codec_internal.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct VP9Common;
|
|
||||||
struct VP9Decoder;
|
|
||||||
|
|
||||||
// WorkerData for the FrameWorker thread. It contains all the information of
|
|
||||||
// the worker and decode structures for decoding a frame.
|
|
||||||
typedef struct FrameWorkerData {
|
|
||||||
struct VP9Decoder *pbi;
|
|
||||||
const uint8_t *data;
|
|
||||||
const uint8_t *data_end;
|
|
||||||
size_t data_size;
|
|
||||||
void *user_priv;
|
|
||||||
int result;
|
|
||||||
int worker_id;
|
|
||||||
int received_frame;
|
|
||||||
|
|
||||||
// scratch_buffer is used in frame parallel mode only.
|
|
||||||
// It is used to make a copy of the compressed data.
|
|
||||||
uint8_t *scratch_buffer;
|
|
||||||
size_t scratch_buffer_size;
|
|
||||||
|
|
||||||
#if CONFIG_MULTITHREAD
|
|
||||||
pthread_mutex_t stats_mutex;
|
|
||||||
pthread_cond_t stats_cond;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int frame_context_ready; // Current frame's context is ready to read.
|
|
||||||
int frame_decoded; // Finished decoding current frame.
|
|
||||||
} FrameWorkerData;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} // extern "C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // VP9_DECODER_VP9_DTHREAD_H_
|
|
||||||
@@ -898,12 +898,6 @@ static vpx_codec_err_t encoder_init(vpx_codec_ctx_t *ctx,
|
|||||||
priv->buffer_pool = (BufferPool *)vpx_calloc(1, sizeof(BufferPool));
|
priv->buffer_pool = (BufferPool *)vpx_calloc(1, sizeof(BufferPool));
|
||||||
if (priv->buffer_pool == NULL) return VPX_CODEC_MEM_ERROR;
|
if (priv->buffer_pool == NULL) return VPX_CODEC_MEM_ERROR;
|
||||||
|
|
||||||
#if CONFIG_MULTITHREAD
|
|
||||||
if (pthread_mutex_init(&priv->buffer_pool->pool_mutex, NULL)) {
|
|
||||||
return VPX_CODEC_MEM_ERROR;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ctx->config.enc) {
|
if (ctx->config.enc) {
|
||||||
// Update the reference to the config structure to an internal copy.
|
// Update the reference to the config structure to an internal copy.
|
||||||
priv->cfg = *ctx->config.enc;
|
priv->cfg = *ctx->config.enc;
|
||||||
@@ -935,9 +929,6 @@ static vpx_codec_err_t encoder_init(vpx_codec_ctx_t *ctx,
|
|||||||
static vpx_codec_err_t encoder_destroy(vpx_codec_alg_priv_t *ctx) {
|
static vpx_codec_err_t encoder_destroy(vpx_codec_alg_priv_t *ctx) {
|
||||||
free(ctx->cx_data);
|
free(ctx->cx_data);
|
||||||
vp9_remove_compressor(ctx->cpi);
|
vp9_remove_compressor(ctx->cpi);
|
||||||
#if CONFIG_MULTITHREAD
|
|
||||||
pthread_mutex_destroy(&ctx->buffer_pool->pool_mutex);
|
|
||||||
#endif
|
|
||||||
vpx_free(ctx->buffer_pool);
|
vpx_free(ctx->buffer_pool);
|
||||||
vpx_free(ctx);
|
vpx_free(ctx);
|
||||||
return VPX_CODEC_OK;
|
return VPX_CODEC_OK;
|
||||||
|
|||||||
@@ -57,33 +57,8 @@ static vpx_codec_err_t decoder_init(vpx_codec_ctx_t *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static vpx_codec_err_t decoder_destroy(vpx_codec_alg_priv_t *ctx) {
|
static vpx_codec_err_t decoder_destroy(vpx_codec_alg_priv_t *ctx) {
|
||||||
if (ctx->frame_workers != NULL) {
|
if (ctx->pbi != NULL) {
|
||||||
int i;
|
vp9_decoder_remove(ctx->pbi);
|
||||||
// Shutdown all threads before reclaiming any memory. The frame-level
|
|
||||||
// parallel decoder may access data from another worker.
|
|
||||||
for (i = 0; i < ctx->num_frame_workers; ++i) {
|
|
||||||
VPxWorker *const worker = &ctx->frame_workers[i];
|
|
||||||
vpx_get_worker_interface()->end(worker);
|
|
||||||
}
|
|
||||||
for (i = 0; i < ctx->num_frame_workers; ++i) {
|
|
||||||
VPxWorker *const worker = &ctx->frame_workers[i];
|
|
||||||
FrameWorkerData *const frame_worker_data =
|
|
||||||
(FrameWorkerData *)worker->data1;
|
|
||||||
vp9_remove_common(&frame_worker_data->pbi->common);
|
|
||||||
#if CONFIG_VP9_POSTPROC
|
|
||||||
vp9_free_postproc_buffers(&frame_worker_data->pbi->common);
|
|
||||||
#endif
|
|
||||||
vp9_decoder_remove(frame_worker_data->pbi);
|
|
||||||
vpx_free(frame_worker_data->scratch_buffer);
|
|
||||||
#if CONFIG_MULTITHREAD
|
|
||||||
pthread_mutex_destroy(&frame_worker_data->stats_mutex);
|
|
||||||
pthread_cond_destroy(&frame_worker_data->stats_cond);
|
|
||||||
#endif
|
|
||||||
vpx_free(frame_worker_data);
|
|
||||||
}
|
|
||||||
#if CONFIG_MULTITHREAD
|
|
||||||
pthread_mutex_destroy(&ctx->buffer_pool->pool_mutex);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->buffer_pool) {
|
if (ctx->buffer_pool) {
|
||||||
@@ -91,7 +66,6 @@ static vpx_codec_err_t decoder_destroy(vpx_codec_alg_priv_t *ctx) {
|
|||||||
vp9_free_internal_frame_buffers(&ctx->buffer_pool->int_frame_buffers);
|
vp9_free_internal_frame_buffers(&ctx->buffer_pool->int_frame_buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
vpx_free(ctx->frame_workers);
|
|
||||||
vpx_free(ctx->buffer_pool);
|
vpx_free(ctx->buffer_pool);
|
||||||
vpx_free(ctx);
|
vpx_free(ctx);
|
||||||
return VPX_CODEC_OK;
|
return VPX_CODEC_OK;
|
||||||
@@ -225,12 +199,7 @@ static vpx_codec_err_t update_error_state(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void init_buffer_callbacks(vpx_codec_alg_priv_t *ctx) {
|
static void init_buffer_callbacks(vpx_codec_alg_priv_t *ctx) {
|
||||||
int i;
|
VP9_COMMON *const cm = &ctx->pbi->common;
|
||||||
|
|
||||||
for (i = 0; i < ctx->num_frame_workers; ++i) {
|
|
||||||
VPxWorker *const worker = &ctx->frame_workers[i];
|
|
||||||
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
|
||||||
VP9_COMMON *const cm = &frame_worker_data->pbi->common;
|
|
||||||
BufferPool *const pool = cm->buffer_pool;
|
BufferPool *const pool = cm->buffer_pool;
|
||||||
|
|
||||||
cm->new_fb_idx = INVALID_IDX;
|
cm->new_fb_idx = INVALID_IDX;
|
||||||
@@ -252,7 +221,6 @@ static void init_buffer_callbacks(vpx_codec_alg_priv_t *ctx) {
|
|||||||
pool->cb_priv = &pool->int_frame_buffers;
|
pool->cb_priv = &pool->int_frame_buffers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void set_default_ppflags(vp8_postproc_cfg_t *cfg) {
|
static void set_default_ppflags(vp8_postproc_cfg_t *cfg) {
|
||||||
cfg->post_proc_flag = VP8_DEBLOCK | VP8_DEMACROBLOCK;
|
cfg->post_proc_flag = VP8_DEBLOCK | VP8_DEMACROBLOCK;
|
||||||
@@ -267,87 +235,21 @@ static void set_ppflags(const vpx_codec_alg_priv_t *ctx, vp9_ppflags_t *flags) {
|
|||||||
flags->noise_level = ctx->postproc_cfg.noise_level;
|
flags->noise_level = ctx->postproc_cfg.noise_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int frame_worker_hook(void *arg1, void *arg2) {
|
|
||||||
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)arg1;
|
|
||||||
const uint8_t *data = frame_worker_data->data;
|
|
||||||
(void)arg2;
|
|
||||||
|
|
||||||
frame_worker_data->result = vp9_receive_compressed_data(
|
|
||||||
frame_worker_data->pbi, frame_worker_data->data_size, &data);
|
|
||||||
frame_worker_data->data_end = data;
|
|
||||||
|
|
||||||
if (frame_worker_data->result != 0) {
|
|
||||||
// Check decode result in serial decode.
|
|
||||||
frame_worker_data->pbi->cur_buf->buf.corrupted = 1;
|
|
||||||
frame_worker_data->pbi->need_resync = 1;
|
|
||||||
}
|
|
||||||
return !frame_worker_data->result;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
const VPxWorkerInterface *const winterface = vpx_get_worker_interface();
|
|
||||||
|
|
||||||
ctx->last_show_frame = -1;
|
ctx->last_show_frame = -1;
|
||||||
ctx->need_resync = 1;
|
ctx->need_resync = 1;
|
||||||
ctx->num_frame_workers = 1;
|
|
||||||
ctx->flushed = 0;
|
ctx->flushed = 0;
|
||||||
|
|
||||||
ctx->buffer_pool = (BufferPool *)vpx_calloc(1, sizeof(BufferPool));
|
ctx->buffer_pool = (BufferPool *)vpx_calloc(1, sizeof(BufferPool));
|
||||||
if (ctx->buffer_pool == NULL) return VPX_CODEC_MEM_ERROR;
|
if (ctx->buffer_pool == NULL) return VPX_CODEC_MEM_ERROR;
|
||||||
|
|
||||||
#if CONFIG_MULTITHREAD
|
ctx->pbi = vp9_decoder_create(ctx->buffer_pool);
|
||||||
if (pthread_mutex_init(&ctx->buffer_pool->pool_mutex, NULL)) {
|
if (ctx->pbi == NULL) {
|
||||||
set_error_detail(ctx, "Failed to allocate buffer pool mutex");
|
set_error_detail(ctx, "Failed to allocate decoder");
|
||||||
return VPX_CODEC_MEM_ERROR;
|
return VPX_CODEC_MEM_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
ctx->pbi->max_threads = ctx->cfg.threads;
|
||||||
|
ctx->pbi->inv_tile_order = ctx->invert_tile_order;
|
||||||
ctx->frame_workers = (VPxWorker *)vpx_malloc(ctx->num_frame_workers *
|
|
||||||
sizeof(*ctx->frame_workers));
|
|
||||||
if (ctx->frame_workers == NULL) {
|
|
||||||
set_error_detail(ctx, "Failed to allocate frame_workers");
|
|
||||||
return VPX_CODEC_MEM_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ctx->num_frame_workers; ++i) {
|
|
||||||
VPxWorker *const worker = &ctx->frame_workers[i];
|
|
||||||
FrameWorkerData *frame_worker_data = NULL;
|
|
||||||
winterface->init(worker);
|
|
||||||
worker->data1 = vpx_memalign(32, sizeof(FrameWorkerData));
|
|
||||||
if (worker->data1 == NULL) {
|
|
||||||
set_error_detail(ctx, "Failed to allocate frame_worker_data");
|
|
||||||
return VPX_CODEC_MEM_ERROR;
|
|
||||||
}
|
|
||||||
frame_worker_data = (FrameWorkerData *)worker->data1;
|
|
||||||
frame_worker_data->pbi = vp9_decoder_create(ctx->buffer_pool);
|
|
||||||
if (frame_worker_data->pbi == NULL) {
|
|
||||||
set_error_detail(ctx, "Failed to allocate frame_worker_data");
|
|
||||||
return VPX_CODEC_MEM_ERROR;
|
|
||||||
}
|
|
||||||
frame_worker_data->worker_id = i;
|
|
||||||
frame_worker_data->scratch_buffer = NULL;
|
|
||||||
frame_worker_data->scratch_buffer_size = 0;
|
|
||||||
frame_worker_data->frame_context_ready = 0;
|
|
||||||
frame_worker_data->received_frame = 0;
|
|
||||||
#if CONFIG_MULTITHREAD
|
|
||||||
if (pthread_mutex_init(&frame_worker_data->stats_mutex, NULL)) {
|
|
||||||
set_error_detail(ctx, "Failed to allocate frame_worker_data mutex");
|
|
||||||
return VPX_CODEC_MEM_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pthread_cond_init(&frame_worker_data->stats_cond, NULL)) {
|
|
||||||
set_error_detail(ctx, "Failed to allocate frame_worker_data cond");
|
|
||||||
return VPX_CODEC_MEM_ERROR;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// If decoding in serial mode, FrameWorker thread could create tile worker
|
|
||||||
// thread or loopfilter thread.
|
|
||||||
frame_worker_data->pbi->max_threads = ctx->cfg.threads;
|
|
||||||
|
|
||||||
frame_worker_data->pbi->inv_tile_order = ctx->invert_tile_order;
|
|
||||||
worker->hook = (VPxWorkerHook)frame_worker_hook;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If postprocessing was enabled by the application and a
|
// If postprocessing was enabled by the application and a
|
||||||
// configuration has not been provided, default it.
|
// configuration has not been provided, default it.
|
||||||
@@ -361,7 +263,7 @@ static vpx_codec_err_t init_decoder(vpx_codec_alg_priv_t *ctx) {
|
|||||||
|
|
||||||
static INLINE void check_resync(vpx_codec_alg_priv_t *const ctx,
|
static INLINE void check_resync(vpx_codec_alg_priv_t *const ctx,
|
||||||
const VP9Decoder *const pbi) {
|
const VP9Decoder *const pbi) {
|
||||||
// Clear resync flag if worker got a key frame or intra only frame.
|
// Clear resync flag if the decoder got a key frame or intra only frame.
|
||||||
if (ctx->need_resync == 1 && pbi->need_resync == 0 &&
|
if (ctx->need_resync == 1 && pbi->need_resync == 0 &&
|
||||||
(pbi->common.intra_only || pbi->common.frame_type == KEY_FRAME))
|
(pbi->common.intra_only || pbi->common.frame_type == KEY_FRAME))
|
||||||
ctx->need_resync = 0;
|
ctx->need_resync = 0;
|
||||||
@@ -370,7 +272,6 @@ 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 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
|
||||||
@@ -386,31 +287,22 @@ static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx,
|
|||||||
if (!ctx->si.is_kf && !is_intra_only) return VPX_CODEC_ERROR;
|
if (!ctx->si.is_kf && !is_intra_only) return VPX_CODEC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
ctx->user_priv = user_priv;
|
||||||
VPxWorker *const worker = ctx->frame_workers;
|
|
||||||
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
|
||||||
frame_worker_data->data = *data;
|
|
||||||
frame_worker_data->data_size = data_sz;
|
|
||||||
frame_worker_data->user_priv = user_priv;
|
|
||||||
frame_worker_data->received_frame = 1;
|
|
||||||
|
|
||||||
// Set these even if already initialized. The caller may have changed the
|
// Set these even if already initialized. The caller may have changed the
|
||||||
// decrypt config between frames.
|
// decrypt config between frames.
|
||||||
frame_worker_data->pbi->decrypt_cb = ctx->decrypt_cb;
|
ctx->pbi->decrypt_cb = ctx->decrypt_cb;
|
||||||
frame_worker_data->pbi->decrypt_state = ctx->decrypt_state;
|
ctx->pbi->decrypt_state = ctx->decrypt_state;
|
||||||
|
|
||||||
worker->had_error = 0;
|
if (vp9_receive_compressed_data(ctx->pbi, data_sz, data)) {
|
||||||
winterface->execute(worker);
|
ctx->pbi->cur_buf->buf.corrupted = 1;
|
||||||
|
ctx->pbi->need_resync = 1;
|
||||||
// Update data pointer after decode.
|
ctx->need_resync = 1;
|
||||||
*data = frame_worker_data->data_end;
|
return update_error_state(ctx, &ctx->pbi->common.error);
|
||||||
|
|
||||||
if (worker->had_error)
|
|
||||||
return update_error_state(ctx, &frame_worker_data->pbi->common.error);
|
|
||||||
|
|
||||||
check_resync(ctx, frame_worker_data->pbi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_resync(ctx, ctx->pbi);
|
||||||
|
|
||||||
return VPX_CODEC_OK;
|
return VPX_CODEC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,8 +323,8 @@ static vpx_codec_err_t decoder_decode(vpx_codec_alg_priv_t *ctx,
|
|||||||
// Reset flushed when receiving a valid frame.
|
// Reset flushed when receiving a valid frame.
|
||||||
ctx->flushed = 0;
|
ctx->flushed = 0;
|
||||||
|
|
||||||
// Initialize the decoder workers on the first frame.
|
// Initialize the decoder on the first frame.
|
||||||
if (ctx->frame_workers == NULL) {
|
if (ctx->pbi == NULL) {
|
||||||
const vpx_codec_err_t res = init_decoder(ctx);
|
const vpx_codec_err_t res = init_decoder(ctx);
|
||||||
if (res != VPX_CODEC_OK) return res;
|
if (res != VPX_CODEC_OK) return res;
|
||||||
}
|
}
|
||||||
@@ -488,36 +380,20 @@ static vpx_image_t *decoder_get_frame(vpx_codec_alg_priv_t *ctx,
|
|||||||
|
|
||||||
// iter acts as a flip flop, so an image is only returned on the first
|
// iter acts as a flip flop, so an image is only returned on the first
|
||||||
// call to get_frame.
|
// call to get_frame.
|
||||||
if (*iter == NULL && ctx->frame_workers != NULL) {
|
if (*iter == NULL && ctx->pbi != NULL) {
|
||||||
YV12_BUFFER_CONFIG sd;
|
YV12_BUFFER_CONFIG sd;
|
||||||
vp9_ppflags_t flags = { 0, 0, 0 };
|
vp9_ppflags_t flags = { 0, 0, 0 };
|
||||||
const VPxWorkerInterface *const winterface = vpx_get_worker_interface();
|
|
||||||
VPxWorker *const worker = &ctx->frame_workers[0];
|
|
||||||
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
|
||||||
if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC) set_ppflags(ctx, &flags);
|
if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC) set_ppflags(ctx, &flags);
|
||||||
// Wait for the frame from worker thread.
|
if (vp9_get_raw_frame(ctx->pbi, &sd, &flags) == 0) {
|
||||||
if (winterface->sync(worker)) {
|
VP9_COMMON *const cm = &ctx->pbi->common;
|
||||||
// Check if worker has received any frames.
|
|
||||||
if (frame_worker_data->received_frame == 1) {
|
|
||||||
frame_worker_data->received_frame = 0;
|
|
||||||
check_resync(ctx, frame_worker_data->pbi);
|
|
||||||
}
|
|
||||||
if (vp9_get_raw_frame(frame_worker_data->pbi, &sd, &flags) == 0) {
|
|
||||||
VP9_COMMON *const cm = &frame_worker_data->pbi->common;
|
|
||||||
RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
|
RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
|
||||||
ctx->last_show_frame = frame_worker_data->pbi->common.new_fb_idx;
|
ctx->last_show_frame = ctx->pbi->common.new_fb_idx;
|
||||||
if (ctx->need_resync) return NULL;
|
if (ctx->need_resync) return NULL;
|
||||||
yuvconfig2image(&ctx->img, &sd, frame_worker_data->user_priv);
|
yuvconfig2image(&ctx->img, &sd, ctx->user_priv);
|
||||||
ctx->img.fb_priv = frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv;
|
ctx->img.fb_priv = frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv;
|
||||||
img = &ctx->img;
|
img = &ctx->img;
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Decoding failed. Release the worker thread.
|
|
||||||
frame_worker_data->received_frame = 0;
|
|
||||||
ctx->need_resync = 1;
|
|
||||||
if (ctx->flushed != 1) return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -527,7 +403,7 @@ static vpx_codec_err_t decoder_set_fb_fn(
|
|||||||
vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) {
|
vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) {
|
||||||
if (cb_get == NULL || cb_release == NULL) {
|
if (cb_get == NULL || cb_release == NULL) {
|
||||||
return VPX_CODEC_INVALID_PARAM;
|
return VPX_CODEC_INVALID_PARAM;
|
||||||
} else if (ctx->frame_workers == NULL) {
|
} else if (ctx->pbi == NULL) {
|
||||||
// If the decoder has already been initialized, do not accept changes to
|
// If the decoder has already been initialized, do not accept changes to
|
||||||
// the frame buffer functions.
|
// the frame buffer functions.
|
||||||
ctx->get_ext_fb_cb = cb_get;
|
ctx->get_ext_fb_cb = cb_get;
|
||||||
@@ -546,12 +422,9 @@ 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;
|
||||||
VPxWorker *const worker = ctx->frame_workers;
|
|
||||||
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(
|
||||||
ref_frame_to_vp9_reframe(frame->frame_type),
|
&ctx->pbi->common, ref_frame_to_vp9_reframe(frame->frame_type), &sd);
|
||||||
&sd);
|
|
||||||
} else {
|
} else {
|
||||||
return VPX_CODEC_INVALID_PARAM;
|
return VPX_CODEC_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
@@ -564,11 +437,9 @@ 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;
|
||||||
VPxWorker *const worker = ctx->frame_workers;
|
|
||||||
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(ctx->pbi, (VP9_REFFRAME)frame->frame_type,
|
||||||
(VP9_REFFRAME)frame->frame_type, &sd);
|
&sd);
|
||||||
} else {
|
} else {
|
||||||
return VPX_CODEC_INVALID_PARAM;
|
return VPX_CODEC_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
@@ -580,9 +451,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;
|
||||||
VPxWorker *const worker = ctx->frame_workers;
|
fb = get_ref_frame(&ctx->pbi->common, data->idx);
|
||||||
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
|
||||||
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;
|
||||||
yuvconfig2image(&data->img, fb, NULL);
|
yuvconfig2image(&data->img, fb, NULL);
|
||||||
return VPX_CODEC_OK;
|
return VPX_CODEC_OK;
|
||||||
@@ -613,9 +482,8 @@ static vpx_codec_err_t ctrl_set_postproc(vpx_codec_alg_priv_t *ctx,
|
|||||||
static vpx_codec_err_t ctrl_get_quantizer(vpx_codec_alg_priv_t *ctx,
|
static vpx_codec_err_t ctrl_get_quantizer(vpx_codec_alg_priv_t *ctx,
|
||||||
va_list args) {
|
va_list args) {
|
||||||
int *const arg = va_arg(args, int *);
|
int *const arg = va_arg(args, int *);
|
||||||
if (arg == NULL) return VPX_CODEC_INVALID_PARAM;
|
if (arg == NULL || ctx->pbi == NULL) return VPX_CODEC_INVALID_PARAM;
|
||||||
*arg =
|
*arg = ctx->pbi->common.base_qindex;
|
||||||
((FrameWorkerData *)ctx->frame_workers[0].data1)->pbi->common.base_qindex;
|
|
||||||
return VPX_CODEC_OK;
|
return VPX_CODEC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -624,11 +492,8 @@ static vpx_codec_err_t ctrl_get_last_ref_updates(vpx_codec_alg_priv_t *ctx,
|
|||||||
int *const update_info = va_arg(args, int *);
|
int *const update_info = va_arg(args, int *);
|
||||||
|
|
||||||
if (update_info) {
|
if (update_info) {
|
||||||
if (ctx->frame_workers) {
|
if (ctx->pbi != NULL) {
|
||||||
VPxWorker *const worker = ctx->frame_workers;
|
*update_info = ctx->pbi->refresh_frame_flags;
|
||||||
FrameWorkerData *const frame_worker_data =
|
|
||||||
(FrameWorkerData *)worker->data1;
|
|
||||||
*update_info = frame_worker_data->pbi->refresh_frame_flags;
|
|
||||||
return VPX_CODEC_OK;
|
return VPX_CODEC_OK;
|
||||||
} else {
|
} else {
|
||||||
return VPX_CODEC_ERROR;
|
return VPX_CODEC_ERROR;
|
||||||
@@ -643,14 +508,9 @@ static vpx_codec_err_t ctrl_get_frame_corrupted(vpx_codec_alg_priv_t *ctx,
|
|||||||
int *corrupted = va_arg(args, int *);
|
int *corrupted = va_arg(args, int *);
|
||||||
|
|
||||||
if (corrupted) {
|
if (corrupted) {
|
||||||
if (ctx->frame_workers) {
|
if (ctx->pbi != NULL) {
|
||||||
VPxWorker *const worker = ctx->frame_workers;
|
RefCntBuffer *const frame_bufs = ctx->pbi->common.buffer_pool->frame_bufs;
|
||||||
FrameWorkerData *const frame_worker_data =
|
if (ctx->pbi->common.frame_to_show == NULL) return VPX_CODEC_ERROR;
|
||||||
(FrameWorkerData *)worker->data1;
|
|
||||||
RefCntBuffer *const frame_bufs =
|
|
||||||
frame_worker_data->pbi->common.buffer_pool->frame_bufs;
|
|
||||||
if (frame_worker_data->pbi->common.frame_to_show == NULL)
|
|
||||||
return VPX_CODEC_ERROR;
|
|
||||||
if (ctx->last_show_frame >= 0)
|
if (ctx->last_show_frame >= 0)
|
||||||
*corrupted = frame_bufs[ctx->last_show_frame].buf.corrupted;
|
*corrupted = frame_bufs[ctx->last_show_frame].buf.corrupted;
|
||||||
return VPX_CODEC_OK;
|
return VPX_CODEC_OK;
|
||||||
@@ -667,11 +527,8 @@ static vpx_codec_err_t ctrl_get_frame_size(vpx_codec_alg_priv_t *ctx,
|
|||||||
int *const frame_size = va_arg(args, int *);
|
int *const frame_size = va_arg(args, int *);
|
||||||
|
|
||||||
if (frame_size) {
|
if (frame_size) {
|
||||||
if (ctx->frame_workers) {
|
if (ctx->pbi != NULL) {
|
||||||
VPxWorker *const worker = ctx->frame_workers;
|
const VP9_COMMON *const cm = &ctx->pbi->common;
|
||||||
FrameWorkerData *const frame_worker_data =
|
|
||||||
(FrameWorkerData *)worker->data1;
|
|
||||||
const VP9_COMMON *const cm = &frame_worker_data->pbi->common;
|
|
||||||
frame_size[0] = cm->width;
|
frame_size[0] = cm->width;
|
||||||
frame_size[1] = cm->height;
|
frame_size[1] = cm->height;
|
||||||
return VPX_CODEC_OK;
|
return VPX_CODEC_OK;
|
||||||
@@ -688,11 +545,8 @@ static vpx_codec_err_t ctrl_get_render_size(vpx_codec_alg_priv_t *ctx,
|
|||||||
int *const render_size = va_arg(args, int *);
|
int *const render_size = va_arg(args, int *);
|
||||||
|
|
||||||
if (render_size) {
|
if (render_size) {
|
||||||
if (ctx->frame_workers) {
|
if (ctx->pbi != NULL) {
|
||||||
VPxWorker *const worker = ctx->frame_workers;
|
const VP9_COMMON *const cm = &ctx->pbi->common;
|
||||||
FrameWorkerData *const frame_worker_data =
|
|
||||||
(FrameWorkerData *)worker->data1;
|
|
||||||
const VP9_COMMON *const cm = &frame_worker_data->pbi->common;
|
|
||||||
render_size[0] = cm->render_width;
|
render_size[0] = cm->render_width;
|
||||||
render_size[1] = cm->render_height;
|
render_size[1] = cm->render_height;
|
||||||
return VPX_CODEC_OK;
|
return VPX_CODEC_OK;
|
||||||
@@ -707,13 +561,10 @@ static vpx_codec_err_t ctrl_get_render_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 *);
|
||||||
VPxWorker *const worker = &ctx->frame_workers[0];
|
|
||||||
|
|
||||||
if (bit_depth) {
|
if (bit_depth) {
|
||||||
if (worker) {
|
if (ctx->pbi != NULL) {
|
||||||
FrameWorkerData *const frame_worker_data =
|
const VP9_COMMON *const cm = &ctx->pbi->common;
|
||||||
(FrameWorkerData *)worker->data1;
|
|
||||||
const VP9_COMMON *const cm = &frame_worker_data->pbi->common;
|
|
||||||
*bit_depth = cm->bit_depth;
|
*bit_depth = cm->bit_depth;
|
||||||
return VPX_CODEC_OK;
|
return VPX_CODEC_OK;
|
||||||
} else {
|
} else {
|
||||||
@@ -752,10 +603,8 @@ static vpx_codec_err_t ctrl_set_byte_alignment(vpx_codec_alg_priv_t *ctx,
|
|||||||
return VPX_CODEC_INVALID_PARAM;
|
return VPX_CODEC_INVALID_PARAM;
|
||||||
|
|
||||||
ctx->byte_alignment = byte_alignment;
|
ctx->byte_alignment = byte_alignment;
|
||||||
if (ctx->frame_workers) {
|
if (ctx->pbi != NULL) {
|
||||||
VPxWorker *const worker = ctx->frame_workers;
|
ctx->pbi->common.byte_alignment = byte_alignment;
|
||||||
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
|
||||||
frame_worker_data->pbi->common.byte_alignment = byte_alignment;
|
|
||||||
}
|
}
|
||||||
return VPX_CODEC_OK;
|
return VPX_CODEC_OK;
|
||||||
}
|
}
|
||||||
@@ -764,10 +613,8 @@ static vpx_codec_err_t ctrl_set_skip_loop_filter(vpx_codec_alg_priv_t *ctx,
|
|||||||
va_list args) {
|
va_list args) {
|
||||||
ctx->skip_loop_filter = va_arg(args, int);
|
ctx->skip_loop_filter = va_arg(args, int);
|
||||||
|
|
||||||
if (ctx->frame_workers) {
|
if (ctx->pbi != NULL) {
|
||||||
VPxWorker *const worker = ctx->frame_workers;
|
ctx->pbi->common.skip_loop_filter = ctx->skip_loop_filter;
|
||||||
FrameWorkerData *const frame_worker_data = (FrameWorkerData *)worker->data1;
|
|
||||||
frame_worker_data->pbi->common.skip_loop_filter = ctx->skip_loop_filter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return VPX_CODEC_OK;
|
return VPX_CODEC_OK;
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ struct vpx_codec_alg_priv {
|
|||||||
vpx_codec_priv_t base;
|
vpx_codec_priv_t base;
|
||||||
vpx_codec_dec_cfg_t cfg;
|
vpx_codec_dec_cfg_t cfg;
|
||||||
vp9_stream_info_t si;
|
vp9_stream_info_t si;
|
||||||
|
VP9Decoder *pbi;
|
||||||
|
void *user_priv;
|
||||||
int postproc_cfg_set;
|
int postproc_cfg_set;
|
||||||
vp8_postproc_cfg_t postproc_cfg;
|
vp8_postproc_cfg_t postproc_cfg;
|
||||||
vpx_decrypt_cb decrypt_cb;
|
vpx_decrypt_cb decrypt_cb;
|
||||||
@@ -31,11 +33,8 @@ struct vpx_codec_alg_priv {
|
|||||||
int byte_alignment;
|
int byte_alignment;
|
||||||
int skip_loop_filter;
|
int skip_loop_filter;
|
||||||
|
|
||||||
// Frame parallel related.
|
|
||||||
VPxWorker *frame_workers;
|
|
||||||
int num_frame_workers;
|
|
||||||
int need_resync; // wait for key/intra-only frame
|
int need_resync; // wait for key/intra-only frame
|
||||||
// BufferPool that holds all reference frames. Shared by all the FrameWorkers.
|
// BufferPool that holds all reference frames.
|
||||||
BufferPool *buffer_pool;
|
BufferPool *buffer_pool;
|
||||||
|
|
||||||
// External frame buffer info to save for VP9 common.
|
// External frame buffer info to save for VP9 common.
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ VP9_DX_SRCS-yes += decoder/vp9_decodeframe.h
|
|||||||
VP9_DX_SRCS-yes += decoder/vp9_detokenize.c
|
VP9_DX_SRCS-yes += decoder/vp9_detokenize.c
|
||||||
VP9_DX_SRCS-yes += decoder/vp9_decodemv.h
|
VP9_DX_SRCS-yes += decoder/vp9_decodemv.h
|
||||||
VP9_DX_SRCS-yes += decoder/vp9_detokenize.h
|
VP9_DX_SRCS-yes += decoder/vp9_detokenize.h
|
||||||
VP9_DX_SRCS-yes += decoder/vp9_dthread.h
|
|
||||||
VP9_DX_SRCS-yes += decoder/vp9_decoder.c
|
VP9_DX_SRCS-yes += decoder/vp9_decoder.c
|
||||||
VP9_DX_SRCS-yes += decoder/vp9_decoder.h
|
VP9_DX_SRCS-yes += decoder/vp9_decoder.h
|
||||||
VP9_DX_SRCS-yes += decoder/vp9_dsubexp.c
|
VP9_DX_SRCS-yes += decoder/vp9_dsubexp.c
|
||||||
|
|||||||
Reference in New Issue
Block a user