/* * Copyright (c) 2016, Alliance for Open Media. All rights reserved. * * This source code is subject to the terms of the BSD 2 Clause License and * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License * was not distributed with this source code in the LICENSE file, you can * obtain it at www.aomedia.org/license/software. If the Alliance for Open * Media Patent License 1.0 was not distributed with this source code in the * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
staticvoid dec_set_mb_mi(CommonModeInfoParams *mi_params, int width, int height, BLOCK_SIZE min_partition_size) {
(void)min_partition_size; // Ensure that the decoded width and height are both multiples of // 8 luma pixels (note: this may only be a multiple of 4 chroma pixels if // subsampling is used). // This simplifies the implementation of various experiments, // eg. cdef, which operates on units of 8x8 luma pixels. constint aligned_width = ALIGN_POWER_OF_TWO(width, 3); constint aligned_height = ALIGN_POWER_OF_TWO(height, 3);
// The jmp_buf is valid only for the duration of the function that calls // setjmp(). Therefore, this function must reset the 'setjmp' field to 0 // before it returns. if (setjmp(pbi->error.jmp)) {
pbi->error.setjmp = 0;
av1_decoder_remove(pbi); return NULL;
}
void av1_dealloc_dec_jobs(struct AV1DecTileMTData *tile_mt_info) { if (tile_mt_info != NULL) { #if CONFIG_MULTITHREAD if (tile_mt_info->job_mutex != NULL) {
pthread_mutex_destroy(tile_mt_info->job_mutex);
aom_free(tile_mt_info->job_mutex);
} #endif
aom_free(tile_mt_info->job_queue); // clear the structure as the source of this call may be a resize in which // case this call will be followed by an _alloc() which may fail.
av1_zero(*tile_mt_info);
}
}
// If any buffer updating is signaled it should be done here. // Consumes a reference to cm->cur_frame. // // This functions returns void. It reports failure by setting // pbi->error.error_code. staticvoid update_frame_buffers(AV1Decoder *pbi, int frame_decoded) { int ref_index = 0, mask;
AV1_COMMON *const cm = &pbi->common;
BufferPool *const pool = cm->buffer_pool;
if (frame_decoded) {
lock_buffer_pool(pool);
// In ext-tile decoding, the camera frame header is only decoded once. So, // we don't update the references here. if (!pbi->camera_frame_header_ready) { // The following for loop needs to release the reference stored in // cm->ref_frame_map[ref_index] before storing a reference to // cm->cur_frame in cm->ref_frame_map[ref_index]. for (mask = cm->current_frame.refresh_frame_flags; mask; mask >>= 1) { if (mask & 1) {
decrease_ref_count(cm->ref_frame_map[ref_index], pool);
cm->ref_frame_map[ref_index] = cm->cur_frame;
++cm->cur_frame->ref_count;
}
++ref_index;
}
}
if (cm->show_existing_frame || cm->show_frame) { if (pbi->output_all_layers) { // Append this frame to the output queue if (pbi->num_output_frames >= MAX_NUM_SPATIAL_LAYERS) { // We can't store the new frame anywhere, so drop it and return an // error
cm->cur_frame->buf.corrupted = 1;
decrease_ref_count(cm->cur_frame, pool);
pbi->error.error_code = AOM_CODEC_UNSUP_BITSTREAM;
} else {
pbi->output_frames[pbi->num_output_frames] = cm->cur_frame;
pbi->num_output_frames++;
}
} else { // Replace any existing output frame
assert(pbi->num_output_frames == 0 || pbi->num_output_frames == 1); if (pbi->num_output_frames > 0) {
decrease_ref_count(pbi->output_frames[0], pool);
}
pbi->output_frames[0] = cm->cur_frame;
pbi->num_output_frames = 1;
}
} else {
decrease_ref_count(cm->cur_frame, pool);
}
unlock_buffer_pool(pool);
} else { // Nothing was decoded, so just drop this frame buffer
lock_buffer_pool(pool);
decrease_ref_count(cm->cur_frame, pool);
unlock_buffer_pool(pool);
}
cm->cur_frame = NULL;
if (!pbi->camera_frame_header_ready) { // Invalidate these references until the next frame starts. for (ref_index = 0; ref_index < INTER_REFS_PER_FRAME; ref_index++) {
cm->remapped_ref_idx[ref_index] = INVALID_IDX;
}
}
}
if (size == 0) { // This is used to signal that we are missing frames. // We do not know if the missing frame(s) was supposed to update // any of the reference buffers, but we act conservative and // mark only the last buffer as corrupted. // // TODO(jkoleszar): Error concealment is undefined and non-normative // at this point, but if it becomes so, [0] may not always be the correct // thing to do here.
RefCntBuffer *ref_buf = get_ref_frame_buf(cm, LAST_FRAME); if (ref_buf != NULL) ref_buf->buf.corrupted = 1;
}
// The jmp_buf is valid only for the duration of the function that calls // setjmp(). Therefore, this function must reset the 'setjmp' field to 0 // before it returns. if (setjmp(pbi->error.jmp)) { const AVxWorkerInterface *const winterface = aom_get_worker_interface(); int i;
pbi->error.setjmp = 0;
// Synchronize all threads immediately as a subsequent decode call may // cause a resize invalidating some allocations.
winterface->sync(&pbi->lf_worker); for (i = 0; i < pbi->num_workers; ++i) {
winterface->sync(&pbi->tile_workers[i]);
}
release_current_frame(pbi); return -1;
}
pbi->error.setjmp = 1;
int frame_decoded =
aom_decode_frame_from_obus(pbi, source, source + size, psource);
#if TXCOEFF_TIMER
cm->cum_txcoeff_timer += cm->txcoeff_timer;
fprintf(stderr, "txb coeff block number: %d, frame time: %ld, cum time %ld in us\n",
cm->txb_count, cm->txcoeff_timer, cm->cum_txcoeff_timer);
cm->txcoeff_timer = 0;
cm->txb_count = 0; #endif
// Note: At this point, this function holds a reference to cm->cur_frame // in the buffer pool. This reference is consumed by update_frame_buffers().
update_frame_buffers(pbi, frame_decoded);
if (frame_decoded) {
pbi->decoding_first_frame = 0;
}
if (!cm->show_existing_frame) { if (cm->seg.enabled) { if (cm->prev_frame &&
(cm->mi_params.mi_rows == cm->prev_frame->mi_rows) &&
(cm->mi_params.mi_cols == cm->prev_frame->mi_cols)) {
cm->last_frame_seg_map = cm->prev_frame->seg_map;
} else {
cm->last_frame_seg_map = NULL;
}
}
}
// Update progress in frame parallel decode.
pbi->error.setjmp = 0;
return 0;
}
// Get the frame at a particular index in the output queue int av1_get_raw_frame(AV1Decoder *pbi, size_t index, YV12_BUFFER_CONFIG **sd,
aom_film_grain_t **grain_params) { if (index >= pbi->num_output_frames) return -1;
*sd = &pbi->output_frames[index]->buf;
*grain_params = &pbi->output_frames[index]->film_grain_params; return 0;
}
// Get the highest-spatial-layer output // TODO(rachelbarker): What should this do? int av1_get_frame_to_show(AV1Decoder *pbi, YV12_BUFFER_CONFIG *frame) { if (pbi->num_output_frames == 0) return -1;
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.