1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* 2233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3233d2500723e5594f3e7c70896ffeeef32b9c950ywan * 4233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Use of this source code is governed by a BSD-style license 5233d2500723e5594f3e7c70896ffeeef32b9c950ywan * that can be found in the LICENSE file in the root of the source 6233d2500723e5594f3e7c70896ffeeef32b9c950ywan * tree. An additional intellectual property rights grant can be found 7233d2500723e5594f3e7c70896ffeeef32b9c950ywan * in the file PATENTS. All contributing project authors may 8233d2500723e5594f3e7c70896ffeeef32b9c950ywan * be found in the AUTHORS file in the root of the source tree. 9233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 10233d2500723e5594f3e7c70896ffeeef32b9c950ywan 11233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <assert.h> 12233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <limits.h> 13233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <stdio.h> 14233d2500723e5594f3e7c70896ffeeef32b9c950ywan 15233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "./vpx_scale_rtcd.h" 16233d2500723e5594f3e7c70896ffeeef32b9c950ywan 17233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx_mem/vpx_mem.h" 18233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx_ports/vpx_timer.h" 19233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx_scale/vpx_scale.h" 20233d2500723e5594f3e7c70896ffeeef32b9c950ywan 21233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_alloccommon.h" 22233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_loopfilter.h" 23233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_onyxc_int.h" 24233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if CONFIG_VP9_POSTPROC 25233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_postproc.h" 26233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 27233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_quant_common.h" 28233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/common/vp9_systemdependent.h" 29233d2500723e5594f3e7c70896ffeeef32b9c950ywan 30233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/decoder/vp9_decodeframe.h" 31233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/decoder/vp9_decoder.h" 32233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/decoder/vp9_detokenize.h" 33233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vp9/decoder/vp9_dthread.h" 34233d2500723e5594f3e7c70896ffeeef32b9c950ywan 35233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define WRITE_RECON_BUFFER 0 36233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if WRITE_RECON_BUFFER == 1 37233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void recon_write_yuv_frame(const char *name, 38233d2500723e5594f3e7c70896ffeeef32b9c950ywan const YV12_BUFFER_CONFIG *s, 39233d2500723e5594f3e7c70896ffeeef32b9c950ywan int w, int _h) { 40233d2500723e5594f3e7c70896ffeeef32b9c950ywan FILE *yuv_file = fopen(name, "ab"); 41233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *src = s->y_buffer; 42233d2500723e5594f3e7c70896ffeeef32b9c950ywan int h = _h; 43233d2500723e5594f3e7c70896ffeeef32b9c950ywan 44233d2500723e5594f3e7c70896ffeeef32b9c950ywan do { 45233d2500723e5594f3e7c70896ffeeef32b9c950ywan fwrite(src, w, 1, yuv_file); 46233d2500723e5594f3e7c70896ffeeef32b9c950ywan src += s->y_stride; 47233d2500723e5594f3e7c70896ffeeef32b9c950ywan } while (--h); 48233d2500723e5594f3e7c70896ffeeef32b9c950ywan 49233d2500723e5594f3e7c70896ffeeef32b9c950ywan src = s->u_buffer; 50233d2500723e5594f3e7c70896ffeeef32b9c950ywan h = (_h + 1) >> 1; 51233d2500723e5594f3e7c70896ffeeef32b9c950ywan w = (w + 1) >> 1; 52233d2500723e5594f3e7c70896ffeeef32b9c950ywan 53233d2500723e5594f3e7c70896ffeeef32b9c950ywan do { 54233d2500723e5594f3e7c70896ffeeef32b9c950ywan fwrite(src, w, 1, yuv_file); 55233d2500723e5594f3e7c70896ffeeef32b9c950ywan src += s->uv_stride; 56233d2500723e5594f3e7c70896ffeeef32b9c950ywan } while (--h); 57233d2500723e5594f3e7c70896ffeeef32b9c950ywan 58233d2500723e5594f3e7c70896ffeeef32b9c950ywan src = s->v_buffer; 59233d2500723e5594f3e7c70896ffeeef32b9c950ywan h = (_h + 1) >> 1; 60233d2500723e5594f3e7c70896ffeeef32b9c950ywan 61233d2500723e5594f3e7c70896ffeeef32b9c950ywan do { 62233d2500723e5594f3e7c70896ffeeef32b9c950ywan fwrite(src, w, 1, yuv_file); 63233d2500723e5594f3e7c70896ffeeef32b9c950ywan src += s->uv_stride; 64233d2500723e5594f3e7c70896ffeeef32b9c950ywan } while (--h); 65233d2500723e5594f3e7c70896ffeeef32b9c950ywan 66233d2500723e5594f3e7c70896ffeeef32b9c950ywan fclose(yuv_file); 67233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 68233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 69233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if WRITE_RECON_BUFFER == 2 70233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid write_dx_frame_to_file(YV12_BUFFER_CONFIG *frame, int this_frame) { 71233d2500723e5594f3e7c70896ffeeef32b9c950ywan // write the frame 72233d2500723e5594f3e7c70896ffeeef32b9c950ywan FILE *yframe; 73233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 74233d2500723e5594f3e7c70896ffeeef32b9c950ywan char filename[255]; 75233d2500723e5594f3e7c70896ffeeef32b9c950ywan 76233d2500723e5594f3e7c70896ffeeef32b9c950ywan snprintf(filename, sizeof(filename)-1, "dx\\y%04d.raw", this_frame); 77233d2500723e5594f3e7c70896ffeeef32b9c950ywan yframe = fopen(filename, "wb"); 78233d2500723e5594f3e7c70896ffeeef32b9c950ywan 79233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < frame->y_height; i++) 80233d2500723e5594f3e7c70896ffeeef32b9c950ywan fwrite(frame->y_buffer + i * frame->y_stride, 81233d2500723e5594f3e7c70896ffeeef32b9c950ywan frame->y_width, 1, yframe); 82233d2500723e5594f3e7c70896ffeeef32b9c950ywan 83233d2500723e5594f3e7c70896ffeeef32b9c950ywan fclose(yframe); 84233d2500723e5594f3e7c70896ffeeef32b9c950ywan snprintf(filename, sizeof(filename)-1, "dx\\u%04d.raw", this_frame); 85233d2500723e5594f3e7c70896ffeeef32b9c950ywan yframe = fopen(filename, "wb"); 86233d2500723e5594f3e7c70896ffeeef32b9c950ywan 87233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < frame->uv_height; i++) 88233d2500723e5594f3e7c70896ffeeef32b9c950ywan fwrite(frame->u_buffer + i * frame->uv_stride, 89233d2500723e5594f3e7c70896ffeeef32b9c950ywan frame->uv_width, 1, yframe); 90233d2500723e5594f3e7c70896ffeeef32b9c950ywan 91233d2500723e5594f3e7c70896ffeeef32b9c950ywan fclose(yframe); 92233d2500723e5594f3e7c70896ffeeef32b9c950ywan snprintf(filename, sizeof(filename)-1, "dx\\v%04d.raw", this_frame); 93233d2500723e5594f3e7c70896ffeeef32b9c950ywan yframe = fopen(filename, "wb"); 94233d2500723e5594f3e7c70896ffeeef32b9c950ywan 95233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < frame->uv_height; i++) 96233d2500723e5594f3e7c70896ffeeef32b9c950ywan fwrite(frame->v_buffer + i * frame->uv_stride, 97233d2500723e5594f3e7c70896ffeeef32b9c950ywan frame->uv_width, 1, yframe); 98233d2500723e5594f3e7c70896ffeeef32b9c950ywan 99233d2500723e5594f3e7c70896ffeeef32b9c950ywan fclose(yframe); 100233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 101233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 102233d2500723e5594f3e7c70896ffeeef32b9c950ywan 103233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp9_initialize_dec() { 104233d2500723e5594f3e7c70896ffeeef32b9c950ywan static int init_done = 0; 105233d2500723e5594f3e7c70896ffeeef32b9c950ywan 106233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!init_done) { 107233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_init_neighbors(); 108233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_init_quant_tables(); 109233d2500723e5594f3e7c70896ffeeef32b9c950ywan init_done = 1; 110233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 111233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 112233d2500723e5594f3e7c70896ffeeef32b9c950ywan 113233d2500723e5594f3e7c70896ffeeef32b9c950ywanVP9D_COMP *vp9_create_decompressor(const VP9D_CONFIG *oxcf) { 114233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9D_COMP *const pbi = vpx_memalign(32, sizeof(VP9D_COMP)); 115233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = pbi ? &pbi->common : NULL; 116233d2500723e5594f3e7c70896ffeeef32b9c950ywan 117233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!cm) 118233d2500723e5594f3e7c70896ffeeef32b9c950ywan return NULL; 119233d2500723e5594f3e7c70896ffeeef32b9c950ywan 120233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_zero(*pbi); 121233d2500723e5594f3e7c70896ffeeef32b9c950ywan 122233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Initialize the references to not point to any frame buffers. 123233d2500723e5594f3e7c70896ffeeef32b9c950ywan memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map)); 124233d2500723e5594f3e7c70896ffeeef32b9c950ywan 125233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (setjmp(cm->error.jmp)) { 126233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->error.setjmp = 0; 127233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_remove_decompressor(pbi); 128233d2500723e5594f3e7c70896ffeeef32b9c950ywan return NULL; 129233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 130233d2500723e5594f3e7c70896ffeeef32b9c950ywan 131233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->error.setjmp = 1; 132233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_initialize_dec(); 133233d2500723e5594f3e7c70896ffeeef32b9c950ywan 134233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_rtcd(); 135233d2500723e5594f3e7c70896ffeeef32b9c950ywan 136233d2500723e5594f3e7c70896ffeeef32b9c950ywan pbi->oxcf = *oxcf; 137233d2500723e5594f3e7c70896ffeeef32b9c950ywan pbi->ready_for_new_data = 1; 138233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->current_video_frame = 0; 139233d2500723e5594f3e7c70896ffeeef32b9c950ywan 140233d2500723e5594f3e7c70896ffeeef32b9c950ywan // vp9_init_dequantizer() is first called here. Add check in 141233d2500723e5594f3e7c70896ffeeef32b9c950ywan // frame_init_dequantizer() to avoid unnecessary calling of 142233d2500723e5594f3e7c70896ffeeef32b9c950ywan // vp9_init_dequantizer() for every frame. 143233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_init_dequantizer(cm); 144233d2500723e5594f3e7c70896ffeeef32b9c950ywan 145233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_loop_filter_init(cm); 146233d2500723e5594f3e7c70896ffeeef32b9c950ywan 147233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->error.setjmp = 0; 148233d2500723e5594f3e7c70896ffeeef32b9c950ywan pbi->decoded_key_frame = 0; 149233d2500723e5594f3e7c70896ffeeef32b9c950ywan 150233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_worker_init(&pbi->lf_worker); 151233d2500723e5594f3e7c70896ffeeef32b9c950ywan 152233d2500723e5594f3e7c70896ffeeef32b9c950ywan return pbi; 153233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 154233d2500723e5594f3e7c70896ffeeef32b9c950ywan 155233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid vp9_remove_decompressor(VP9D_COMP *pbi) { 156233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &pbi->common; 157233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 158233d2500723e5594f3e7c70896ffeeef32b9c950ywan 159233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_remove_common(cm); 160233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_worker_end(&pbi->lf_worker); 161233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_free(pbi->lf_worker.data1); 162233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < pbi->num_tile_workers; ++i) { 163233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9Worker *const worker = &pbi->tile_workers[i]; 164233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_worker_end(worker); 165233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_free(worker->data1); 166233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_free(worker->data2); 167233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 168233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_free(pbi->tile_workers); 169233d2500723e5594f3e7c70896ffeeef32b9c950ywan 170233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (pbi->num_tile_workers) { 171233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int sb_rows = 172233d2500723e5594f3e7c70896ffeeef32b9c950ywan mi_cols_aligned_to_sb(cm->mi_rows) >> MI_BLOCK_SIZE_LOG2; 173233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_loop_filter_dealloc(&pbi->lf_row_sync, sb_rows); 174233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 175233d2500723e5594f3e7c70896ffeeef32b9c950ywan 176233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_free(pbi); 177233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 178233d2500723e5594f3e7c70896ffeeef32b9c950ywan 179233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int equal_dimensions(const YV12_BUFFER_CONFIG *a, 180233d2500723e5594f3e7c70896ffeeef32b9c950ywan const YV12_BUFFER_CONFIG *b) { 181233d2500723e5594f3e7c70896ffeeef32b9c950ywan return a->y_height == b->y_height && a->y_width == b->y_width && 182233d2500723e5594f3e7c70896ffeeef32b9c950ywan a->uv_height == b->uv_height && a->uv_width == b->uv_width; 183233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 184233d2500723e5594f3e7c70896ffeeef32b9c950ywan 185233d2500723e5594f3e7c70896ffeeef32b9c950ywanvpx_codec_err_t vp9_copy_reference_dec(VP9D_COMP *pbi, 186233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_REFFRAME ref_frame_flag, 187233d2500723e5594f3e7c70896ffeeef32b9c950ywan YV12_BUFFER_CONFIG *sd) { 188233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *cm = &pbi->common; 189233d2500723e5594f3e7c70896ffeeef32b9c950ywan 190233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* TODO(jkoleszar): The decoder doesn't have any real knowledge of what the 191233d2500723e5594f3e7c70896ffeeef32b9c950ywan * encoder is using the frame buffers for. This is just a stub to keep the 192233d2500723e5594f3e7c70896ffeeef32b9c950ywan * vpxenc --test-decode functionality working, and will be replaced in a 193233d2500723e5594f3e7c70896ffeeef32b9c950ywan * later commit that adds VP9-specific controls for this functionality. 194233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 195233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ref_frame_flag == VP9_LAST_FLAG) { 196233d2500723e5594f3e7c70896ffeeef32b9c950ywan const YV12_BUFFER_CONFIG *const cfg = 197233d2500723e5594f3e7c70896ffeeef32b9c950ywan &cm->frame_bufs[cm->ref_frame_map[0]].buf; 198233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!equal_dimensions(cfg, sd)) 199233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_internal_error(&cm->error, VPX_CODEC_ERROR, 200233d2500723e5594f3e7c70896ffeeef32b9c950ywan "Incorrect buffer dimensions"); 201233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 202233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp8_yv12_copy_frame(cfg, sd); 203233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 204233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_internal_error(&cm->error, VPX_CODEC_ERROR, 205233d2500723e5594f3e7c70896ffeeef32b9c950ywan "Invalid reference frame"); 206233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 207233d2500723e5594f3e7c70896ffeeef32b9c950ywan 208233d2500723e5594f3e7c70896ffeeef32b9c950ywan return cm->error.error_code; 209233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 210233d2500723e5594f3e7c70896ffeeef32b9c950ywan 211233d2500723e5594f3e7c70896ffeeef32b9c950ywan 212233d2500723e5594f3e7c70896ffeeef32b9c950ywanvpx_codec_err_t vp9_set_reference_dec(VP9_COMMON *cm, 213233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_REFFRAME ref_frame_flag, 214233d2500723e5594f3e7c70896ffeeef32b9c950ywan YV12_BUFFER_CONFIG *sd) { 215233d2500723e5594f3e7c70896ffeeef32b9c950ywan RefBuffer *ref_buf = NULL; 216233d2500723e5594f3e7c70896ffeeef32b9c950ywan 217233d2500723e5594f3e7c70896ffeeef32b9c950ywan // TODO(jkoleszar): The decoder doesn't have any real knowledge of what the 218233d2500723e5594f3e7c70896ffeeef32b9c950ywan // encoder is using the frame buffers for. This is just a stub to keep the 219233d2500723e5594f3e7c70896ffeeef32b9c950ywan // vpxenc --test-decode functionality working, and will be replaced in a 220233d2500723e5594f3e7c70896ffeeef32b9c950ywan // later commit that adds VP9-specific controls for this functionality. 221233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ref_frame_flag == VP9_LAST_FLAG) { 222233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_buf = &cm->frame_refs[0]; 223233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (ref_frame_flag == VP9_GOLD_FLAG) { 224233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_buf = &cm->frame_refs[1]; 225233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (ref_frame_flag == VP9_ALT_FLAG) { 226233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_buf = &cm->frame_refs[2]; 227233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 228233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_internal_error(&cm->error, VPX_CODEC_ERROR, 229233d2500723e5594f3e7c70896ffeeef32b9c950ywan "Invalid reference frame"); 230233d2500723e5594f3e7c70896ffeeef32b9c950ywan return cm->error.error_code; 231233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 232233d2500723e5594f3e7c70896ffeeef32b9c950ywan 233233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!equal_dimensions(ref_buf->buf, sd)) { 234233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_internal_error(&cm->error, VPX_CODEC_ERROR, 235233d2500723e5594f3e7c70896ffeeef32b9c950ywan "Incorrect buffer dimensions"); 236233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 237233d2500723e5594f3e7c70896ffeeef32b9c950ywan int *ref_fb_ptr = &ref_buf->idx; 238233d2500723e5594f3e7c70896ffeeef32b9c950ywan 239233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Find an empty frame buffer. 240233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int free_fb = get_free_fb(cm); 241233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Decrease ref_count since it will be increased again in 242233d2500723e5594f3e7c70896ffeeef32b9c950ywan // ref_cnt_fb() below. 243233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->frame_bufs[free_fb].ref_count--; 244233d2500723e5594f3e7c70896ffeeef32b9c950ywan 245233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Manage the reference counters and copy image. 246233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_cnt_fb(cm->frame_bufs, ref_fb_ptr, free_fb); 247233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_buf->buf = &cm->frame_bufs[*ref_fb_ptr].buf; 248233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp8_yv12_copy_frame(sd, ref_buf->buf); 249233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 250233d2500723e5594f3e7c70896ffeeef32b9c950ywan 251233d2500723e5594f3e7c70896ffeeef32b9c950ywan return cm->error.error_code; 252233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 253233d2500723e5594f3e7c70896ffeeef32b9c950ywan 254233d2500723e5594f3e7c70896ffeeef32b9c950ywan 255233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_get_reference_dec(VP9D_COMP *pbi, int index, YV12_BUFFER_CONFIG **fb) { 256233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *cm = &pbi->common; 257233d2500723e5594f3e7c70896ffeeef32b9c950ywan 258233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (index < 0 || index >= REF_FRAMES) 259233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 260233d2500723e5594f3e7c70896ffeeef32b9c950ywan 261233d2500723e5594f3e7c70896ffeeef32b9c950ywan *fb = &cm->frame_bufs[cm->ref_frame_map[index]].buf; 262233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 263233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 264233d2500723e5594f3e7c70896ffeeef32b9c950ywan 265233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* If any buffer updating is signaled it should be done here. */ 266233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void swap_frame_buffers(VP9D_COMP *pbi) { 267233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ref_index = 0, mask; 268233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &pbi->common; 269233d2500723e5594f3e7c70896ffeeef32b9c950ywan 270233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) { 271233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mask & 1) { 272233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int old_idx = cm->ref_frame_map[ref_index]; 273233d2500723e5594f3e7c70896ffeeef32b9c950ywan ref_cnt_fb(cm->frame_bufs, &cm->ref_frame_map[ref_index], 274233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->new_fb_idx); 275233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (old_idx >= 0 && cm->frame_bufs[old_idx].ref_count == 0) 276233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->release_fb_cb(cm->cb_priv, 277233d2500723e5594f3e7c70896ffeeef32b9c950ywan &cm->frame_bufs[old_idx].raw_frame_buffer); 278233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 279233d2500723e5594f3e7c70896ffeeef32b9c950ywan ++ref_index; 280233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 281233d2500723e5594f3e7c70896ffeeef32b9c950ywan 282233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->frame_to_show = get_frame_new_buffer(cm); 283233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->frame_bufs[cm->new_fb_idx].ref_count--; 284233d2500723e5594f3e7c70896ffeeef32b9c950ywan 285233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Invalidate these references until the next frame starts. 286233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (ref_index = 0; ref_index < 3; ref_index++) 287233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->frame_refs[ref_index].idx = INT_MAX; 288233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 289233d2500723e5594f3e7c70896ffeeef32b9c950ywan 290233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_receive_compressed_data(VP9D_COMP *pbi, 291233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t size, const uint8_t **psource, 292233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t time_stamp) { 293233d2500723e5594f3e7c70896ffeeef32b9c950ywan VP9_COMMON *const cm = &pbi->common; 294233d2500723e5594f3e7c70896ffeeef32b9c950ywan const uint8_t *source = *psource; 295233d2500723e5594f3e7c70896ffeeef32b9c950ywan int retcode = 0; 296233d2500723e5594f3e7c70896ffeeef32b9c950ywan 297233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->error.error_code = VPX_CODEC_OK; 298233d2500723e5594f3e7c70896ffeeef32b9c950ywan 299233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (size == 0) { 300233d2500723e5594f3e7c70896ffeeef32b9c950ywan // This is used to signal that we are missing frames. 301233d2500723e5594f3e7c70896ffeeef32b9c950ywan // We do not know if the missing frame(s) was supposed to update 302233d2500723e5594f3e7c70896ffeeef32b9c950ywan // any of the reference buffers, but we act conservative and 303233d2500723e5594f3e7c70896ffeeef32b9c950ywan // mark only the last buffer as corrupted. 304233d2500723e5594f3e7c70896ffeeef32b9c950ywan // 305233d2500723e5594f3e7c70896ffeeef32b9c950ywan // TODO(jkoleszar): Error concealment is undefined and non-normative 306233d2500723e5594f3e7c70896ffeeef32b9c950ywan // at this point, but if it becomes so, [0] may not always be the correct 307233d2500723e5594f3e7c70896ffeeef32b9c950ywan // thing to do here. 308233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->frame_refs[0].idx != INT_MAX) 309233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->frame_refs[0].buf->corrupted = 1; 310233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 311233d2500723e5594f3e7c70896ffeeef32b9c950ywan 312233d2500723e5594f3e7c70896ffeeef32b9c950ywan // Check if the previous frame was a frame without any references to it. 313233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->new_fb_idx >= 0 && cm->frame_bufs[cm->new_fb_idx].ref_count == 0) 314233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->release_fb_cb(cm->cb_priv, 315233d2500723e5594f3e7c70896ffeeef32b9c950ywan &cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer); 316233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->new_fb_idx = get_free_fb(cm); 317233d2500723e5594f3e7c70896ffeeef32b9c950ywan 318233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (setjmp(cm->error.jmp)) { 319233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->error.setjmp = 0; 320233d2500723e5594f3e7c70896ffeeef32b9c950ywan 321233d2500723e5594f3e7c70896ffeeef32b9c950ywan // We do not know if the missing frame(s) was supposed to update 322233d2500723e5594f3e7c70896ffeeef32b9c950ywan // any of the reference buffers, but we act conservative and 323233d2500723e5594f3e7c70896ffeeef32b9c950ywan // mark only the last buffer as corrupted. 324233d2500723e5594f3e7c70896ffeeef32b9c950ywan // 325233d2500723e5594f3e7c70896ffeeef32b9c950ywan // TODO(jkoleszar): Error concealment is undefined and non-normative 326233d2500723e5594f3e7c70896ffeeef32b9c950ywan // at this point, but if it becomes so, [0] may not always be the correct 327233d2500723e5594f3e7c70896ffeeef32b9c950ywan // thing to do here. 328233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->frame_refs[0].idx != INT_MAX) 329233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->frame_refs[0].buf->corrupted = 1; 330233d2500723e5594f3e7c70896ffeeef32b9c950ywan 331233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->frame_bufs[cm->new_fb_idx].ref_count > 0) 332233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->frame_bufs[cm->new_fb_idx].ref_count--; 333233d2500723e5594f3e7c70896ffeeef32b9c950ywan 334233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 335233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 336233d2500723e5594f3e7c70896ffeeef32b9c950ywan 337233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->error.setjmp = 1; 338233d2500723e5594f3e7c70896ffeeef32b9c950ywan 339233d2500723e5594f3e7c70896ffeeef32b9c950ywan retcode = vp9_decode_frame(pbi, source, source + size, psource); 340233d2500723e5594f3e7c70896ffeeef32b9c950ywan 341233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (retcode < 0) { 342233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->error.error_code = VPX_CODEC_ERROR; 343233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->error.setjmp = 0; 344233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->frame_bufs[cm->new_fb_idx].ref_count > 0) 345233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->frame_bufs[cm->new_fb_idx].ref_count--; 346233d2500723e5594f3e7c70896ffeeef32b9c950ywan return retcode; 347233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 348233d2500723e5594f3e7c70896ffeeef32b9c950ywan 349233d2500723e5594f3e7c70896ffeeef32b9c950ywan swap_frame_buffers(pbi); 350233d2500723e5594f3e7c70896ffeeef32b9c950ywan 351233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if WRITE_RECON_BUFFER == 2 352233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->show_frame) 353233d2500723e5594f3e7c70896ffeeef32b9c950ywan write_dx_frame_to_file(cm->frame_to_show, 354233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->current_video_frame); 355233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 356233d2500723e5594f3e7c70896ffeeef32b9c950ywan write_dx_frame_to_file(cm->frame_to_show, 357233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->current_video_frame + 1000); 358233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 359233d2500723e5594f3e7c70896ffeeef32b9c950ywan 360233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!pbi->do_loopfilter_inline) { 361233d2500723e5594f3e7c70896ffeeef32b9c950ywan // If multiple threads are used to decode tiles, then we use those threads 362233d2500723e5594f3e7c70896ffeeef32b9c950ywan // to do parallel loopfiltering. 363233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (pbi->num_tile_workers) { 364233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_loop_filter_frame_mt(pbi, cm, &pbi->mb, cm->lf.filter_level, 0, 0); 365233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 366233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_loop_filter_frame(cm, &pbi->mb, cm->lf.filter_level, 0, 0); 367233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 368233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 369233d2500723e5594f3e7c70896ffeeef32b9c950ywan 370233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if WRITE_RECON_BUFFER == 2 371233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->show_frame) 372233d2500723e5594f3e7c70896ffeeef32b9c950ywan write_dx_frame_to_file(cm->frame_to_show, 373233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->current_video_frame + 2000); 374233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 375233d2500723e5594f3e7c70896ffeeef32b9c950ywan write_dx_frame_to_file(cm->frame_to_show, 376233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->current_video_frame + 3000); 377233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 378233d2500723e5594f3e7c70896ffeeef32b9c950ywan 379233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if WRITE_RECON_BUFFER == 1 380233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->show_frame) 381233d2500723e5594f3e7c70896ffeeef32b9c950ywan recon_write_yuv_frame("recon.yuv", cm->frame_to_show, 382233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->width, cm->height); 383233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 384233d2500723e5594f3e7c70896ffeeef32b9c950ywan 385233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_clear_system_state(); 386233d2500723e5594f3e7c70896ffeeef32b9c950ywan 387233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->last_width = cm->width; 388233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->last_height = cm->height; 389233d2500723e5594f3e7c70896ffeeef32b9c950ywan 390233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!cm->show_existing_frame) 391233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->last_show_frame = cm->show_frame; 392233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cm->show_frame) { 393233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!cm->show_existing_frame) 394233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_swap_mi_and_prev_mi(cm); 395233d2500723e5594f3e7c70896ffeeef32b9c950ywan 396233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->current_video_frame++; 397233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 398233d2500723e5594f3e7c70896ffeeef32b9c950ywan 399233d2500723e5594f3e7c70896ffeeef32b9c950ywan pbi->ready_for_new_data = 0; 400233d2500723e5594f3e7c70896ffeeef32b9c950ywan pbi->last_time_stamp = time_stamp; 401233d2500723e5594f3e7c70896ffeeef32b9c950ywan 402233d2500723e5594f3e7c70896ffeeef32b9c950ywan cm->error.setjmp = 0; 403233d2500723e5594f3e7c70896ffeeef32b9c950ywan return retcode; 404233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 405233d2500723e5594f3e7c70896ffeeef32b9c950ywan 406233d2500723e5594f3e7c70896ffeeef32b9c950ywanint vp9_get_raw_frame(VP9D_COMP *pbi, YV12_BUFFER_CONFIG *sd, 407233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t *time_stamp, int64_t *time_end_stamp, 408233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_ppflags_t *flags) { 409233d2500723e5594f3e7c70896ffeeef32b9c950ywan int ret = -1; 410233d2500723e5594f3e7c70896ffeeef32b9c950ywan (void)flags; 411233d2500723e5594f3e7c70896ffeeef32b9c950ywan 412233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (pbi->ready_for_new_data == 1) 413233d2500723e5594f3e7c70896ffeeef32b9c950ywan return ret; 414233d2500723e5594f3e7c70896ffeeef32b9c950ywan 415233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* ie no raw frame to show!!! */ 416233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (pbi->common.show_frame == 0) 417233d2500723e5594f3e7c70896ffeeef32b9c950ywan return ret; 418233d2500723e5594f3e7c70896ffeeef32b9c950ywan 419233d2500723e5594f3e7c70896ffeeef32b9c950ywan pbi->ready_for_new_data = 1; 420233d2500723e5594f3e7c70896ffeeef32b9c950ywan *time_stamp = pbi->last_time_stamp; 421233d2500723e5594f3e7c70896ffeeef32b9c950ywan *time_end_stamp = 0; 422233d2500723e5594f3e7c70896ffeeef32b9c950ywan 423233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if CONFIG_VP9_POSTPROC 424233d2500723e5594f3e7c70896ffeeef32b9c950ywan ret = vp9_post_proc_frame(&pbi->common, sd, flags); 425233d2500723e5594f3e7c70896ffeeef32b9c950ywan#else 426233d2500723e5594f3e7c70896ffeeef32b9c950ywan 427233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (pbi->common.frame_to_show) { 428233d2500723e5594f3e7c70896ffeeef32b9c950ywan *sd = *pbi->common.frame_to_show; 429233d2500723e5594f3e7c70896ffeeef32b9c950ywan sd->y_width = pbi->common.width; 430233d2500723e5594f3e7c70896ffeeef32b9c950ywan sd->y_height = pbi->common.height; 431233d2500723e5594f3e7c70896ffeeef32b9c950ywan sd->uv_width = sd->y_width >> pbi->common.subsampling_x; 432233d2500723e5594f3e7c70896ffeeef32b9c950ywan sd->uv_height = sd->y_height >> pbi->common.subsampling_y; 433233d2500723e5594f3e7c70896ffeeef32b9c950ywan 434233d2500723e5594f3e7c70896ffeeef32b9c950ywan ret = 0; 435233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 436233d2500723e5594f3e7c70896ffeeef32b9c950ywan ret = -1; 437233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 438233d2500723e5594f3e7c70896ffeeef32b9c950ywan 439233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif /*!CONFIG_POSTPROC*/ 440233d2500723e5594f3e7c70896ffeeef32b9c950ywan vp9_clear_system_state(); 441233d2500723e5594f3e7c70896ffeeef32b9c950ywan return ret; 442233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 443