void av1_alloc_cdef_buffers(AV1_COMMON *const cm,
AV1CdefWorkerData **cdef_worker,
AV1CdefSync *cdef_sync, int num_workers,
int init_worker) { const int num_planes = av1_num_planes(cm);
size_t new_linebuf_size[MAX_MB_PLANE] = { 0 };
size_t new_colbuf_size[MAX_MB_PLANE] = { 0 };
size_t new_srcbuf_size = 0;
CdefInfo *const cdef_info = &cm->cdef_info; // Check for configuration change const int num_mi_rows =
(cm->mi_params.mi_rows + MI_SIZE_64X64 - 1) / MI_SIZE_64X64; const int is_num_workers_changed =
cdef_info->allocated_num_workers != num_workers; const int is_cdef_enabled =
cm->seq_params->enable_cdef && !cm->tiles.single_tile_decoding;
// num-bufs=3 represents ping-pong buffers for top linebuf, // followed by bottom linebuf. // ping-pong is to avoid top linebuf over-write by consecutive row.
int num_bufs = 3;
if (num_workers > 1)
num_bufs = (cm->mi_params.mi_rows + MI_SIZE_64X64 - 1) / MI_SIZE_64X64;
// Free src, line and column buffers for worker 0 in case of reallocation
free_cdef_linebuf_conditional(cm, new_linebuf_size);
free_cdef_bufs_conditional(cm, cdef_info->colbuf, &cdef_info->srcbuf,
new_colbuf_size, new_srcbuf_size);
// The flag init_worker indicates if cdef_worker has to be allocated for the // frame. This is passed as 1 always from decoder. At encoder side, it is 0 // when called for parallel frames during FPMT (where cdef_worker is shared // across parallel frames) and 1 otherwise.
if (*cdef_worker != NULL && init_worker) {
if (is_num_workers_changed) { // Free src and column buffers for remaining workers in case of change in // num_workers
for (int idx = cdef_info->allocated_num_workers - 1; idx >= 1; idx--)
free_cdef_bufs((*cdef_worker)[idx].colbuf, &(*cdef_worker)[idx].srcbuf);
aom_free(*cdef_worker);
*cdef_worker = NULL;
} else if (num_workers > 1) { // Free src and column buffers for remaining workers in case of // reallocation
for (int idx = num_workers - 1; idx >= 1; idx--)
free_cdef_bufs_conditional(cm, (*cdef_worker)[idx].colbuf,
&(*cdef_worker)[idx].srcbuf, new_colbuf_size,
new_srcbuf_size);
}
}
if (cdef_info->allocated_mi_rows != num_mi_rows)
free_cdef_row_sync(&cdef_sync->cdef_row_mt, cdef_info->allocated_mi_rows);
// Store allocated sizes for reallocation
cdef_info->allocated_srcbuf_size = new_srcbuf_size;
av1_copy(cdef_info->allocated_colbuf_size, new_colbuf_size);
av1_copy(cdef_info->allocated_linebuf_size, new_linebuf_size); // Store configuration to check change in configuration
cdef_info->allocated_mi_rows = num_mi_rows;
cdef_info->allocated_num_workers = num_workers;
if (cm->rlbs == NULL) {
CHECK_MEM_ERROR(cm, cm->rlbs, aom_malloc(sizeof(RestorationLineBuffers)));
}
// For striped loop restoration, we divide each plane into "stripes", // of height 64 luma pixels but with an offset by RESTORATION_UNIT_OFFSET // luma pixels to match the output from CDEF. We will need to store 2 * // RESTORATION_CTX_VERT lines of data for each stripe.
int mi_h = cm->mi_params.mi_rows; const int ext_h = RESTORATION_UNIT_OFFSET + (mi_h << MI_SIZE_LOG2); const int num_stripes = (ext_h + 63) / 64;
// Now we need to allocate enough space to store the line buffers for the // stripes const int frame_w = cm->superres_upscaled_width; const int use_highbd = cm->seq_params->use_highbitdepth;
for (int p = 0; p < num_planes; ++p) { const int is_uv = p > 0; const int ss_x = is_uv && cm->seq_params->subsampling_x; const int plane_w = ((frame_w + ss_x) >> ss_x) + 2 * RESTORATION_EXTRA_HORZ; const int stride = ALIGN_POWER_OF_TWO(plane_w, 5); const int buf_size = num_stripes * stride * RESTORATION_CTX_VERT
<< use_highbd;
RestorationStripeBoundaries *boundaries = &cm->rst_info[p].boundaries;
int av1_alloc_above_context_buffers(CommonContexts *above_contexts,
int num_tile_rows, int num_mi_cols,
int num_planes) { const int aligned_mi_cols =
ALIGN_POWER_OF_TWO(num_mi_cols, MAX_MIB_SIZE_LOG2);
above_contexts->partition = (PARTITION_CONTEXT **)aom_calloc(
num_tile_rows, sizeof(above_contexts->partition));
if (!above_contexts->partition) return1;
above_contexts->txfm =
(TXFM_CONTEXT **)aom_calloc(num_tile_rows, sizeof(above_contexts->txfm));
if (!above_contexts->txfm) return1;
for (int tile_row = 0; tile_row < num_tile_rows; tile_row++) {
for (int plane_idx = 0; plane_idx < num_planes; plane_idx++) {
above_contexts->entropy[plane_idx][tile_row] =
(ENTROPY_CONTEXT *)aom_calloc(
aligned_mi_cols, sizeof(*above_contexts->entropy[0][tile_row]));
if (!above_contexts->entropy[plane_idx][tile_row]) return1;
}
above_contexts->partition[tile_row] = (PARTITION_CONTEXT *)aom_calloc(
aligned_mi_cols, sizeof(*above_contexts->partition[tile_row]));
if (!above_contexts->partition[tile_row]) return1;
above_contexts->txfm[tile_row] = (TXFM_CONTEXT *)aom_calloc(
aligned_mi_cols, sizeof(*above_contexts->txfm[tile_row]));
if (!above_contexts->txfm[tile_row]) return1;
}
return0;
}
// Allocate the dynamically allocated arrays in 'mi_params' assuming // 'mi_params->set_mb_mi()' was already called earlier to initialize the rest of // the struct members. static int alloc_mi(CommonModeInfoParams *mi_params) { const int aligned_mi_rows = calc_mi_size(mi_params->mi_rows); const int mi_grid_size = mi_params->mi_stride * aligned_mi_rows; const int alloc_size_1d = mi_size_wide[mi_params->mi_alloc_bsize]; const int alloc_mi_size =
mi_params->mi_alloc_stride * (aligned_mi_rows / alloc_size_1d);
if (mi_params->mi_alloc_size < alloc_mi_size ||
mi_params->mi_grid_size < mi_grid_size) {
mi_params->free_mi(mi_params);
mi_params->mi_alloc =
aom_calloc(alloc_mi_size, sizeof(*mi_params->mi_alloc));
if (!mi_params->mi_alloc) return1;
mi_params->mi_alloc_size = alloc_mi_size;
mi_params->mi_grid_base = (MB_MODE_INFO **)aom_calloc(
mi_grid_size, sizeof(*mi_params->mi_grid_base));
if (!mi_params->mi_grid_base) return1;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.