11b362b15af34006e6a11974088a46d42b903418eJohann/*
21b362b15af34006e6a11974088a46d42b903418eJohann *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
31b362b15af34006e6a11974088a46d42b903418eJohann *
41b362b15af34006e6a11974088a46d42b903418eJohann *  Use of this source code is governed by a BSD-style license
51b362b15af34006e6a11974088a46d42b903418eJohann *  that can be found in the LICENSE file in the root of the source
61b362b15af34006e6a11974088a46d42b903418eJohann *  tree. An additional intellectual property rights grant can be found
71b362b15af34006e6a11974088a46d42b903418eJohann *  in the file PATENTS.  All contributing project authors may
81b362b15af34006e6a11974088a46d42b903418eJohann *  be found in the AUTHORS file in the root of the source tree.
91b362b15af34006e6a11974088a46d42b903418eJohann */
101b362b15af34006e6a11974088a46d42b903418eJohann
111b362b15af34006e6a11974088a46d42b903418eJohann#include "vp8/common/onyxc_int.h"
121b362b15af34006e6a11974088a46d42b903418eJohann#if CONFIG_POSTPROC
131b362b15af34006e6a11974088a46d42b903418eJohann#include "vp8/common/postproc.h"
141b362b15af34006e6a11974088a46d42b903418eJohann#endif
151b362b15af34006e6a11974088a46d42b903418eJohann#include "vp8/common/onyxd.h"
161b362b15af34006e6a11974088a46d42b903418eJohann#include "onyxd_int.h"
171b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx_mem/vpx_mem.h"
181b362b15af34006e6a11974088a46d42b903418eJohann#include "vp8/common/alloccommon.h"
191b362b15af34006e6a11974088a46d42b903418eJohann#include "vp8/common/loopfilter.h"
201b362b15af34006e6a11974088a46d42b903418eJohann#include "vp8/common/swapyv12buffer.h"
211b362b15af34006e6a11974088a46d42b903418eJohann#include "vp8/common/threading.h"
221b362b15af34006e6a11974088a46d42b903418eJohann#include "decoderthreading.h"
231b362b15af34006e6a11974088a46d42b903418eJohann#include <stdio.h>
241b362b15af34006e6a11974088a46d42b903418eJohann#include <assert.h>
251b362b15af34006e6a11974088a46d42b903418eJohann
261b362b15af34006e6a11974088a46d42b903418eJohann#include "vp8/common/quant_common.h"
272263fc984bdc858ee931d3e35c87c404de923950Johann#include "vp8/common/reconintra.h"
282263fc984bdc858ee931d3e35c87c404de923950Johann#include "./vpx_dsp_rtcd.h"
29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "./vpx_scale_rtcd.h"
30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vpx_scale/vpx_scale.h"
311b362b15af34006e6a11974088a46d42b903418eJohann#include "vp8/common/systemdependent.h"
327bc9febe8749e98a3812a0dc4380ceae75c29450Johann#include "vpx_ports/system_state.h"
332263fc984bdc858ee931d3e35c87c404de923950Johann#include "vpx_ports/vpx_once.h"
341b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx_ports/vpx_timer.h"
351b362b15af34006e6a11974088a46d42b903418eJohann#include "detokenize.h"
361b362b15af34006e6a11974088a46d42b903418eJohann#if CONFIG_ERROR_CONCEALMENT
371b362b15af34006e6a11974088a46d42b903418eJohann#include "error_concealment.h"
381b362b15af34006e6a11974088a46d42b903418eJohann#endif
391b362b15af34006e6a11974088a46d42b903418eJohann#if ARCH_ARM
401b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx_ports/arm.h"
411b362b15af34006e6a11974088a46d42b903418eJohann#endif
421b362b15af34006e6a11974088a46d42b903418eJohann
431b362b15af34006e6a11974088a46d42b903418eJohannextern void vp8_init_loop_filter(VP8_COMMON *cm);
441b362b15af34006e6a11974088a46d42b903418eJohannextern void vp8cx_init_de_quantizer(VP8D_COMP *pbi);
457bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic int get_free_fb(VP8_COMMON *cm);
467bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void ref_cnt_fb(int *buf, int *idx, int new_idx);
471b362b15af34006e6a11974088a46d42b903418eJohann
482263fc984bdc858ee931d3e35c87c404de923950Johannstatic void initialize_dec(void) {
497bc9febe8749e98a3812a0dc4380ceae75c29450Johann  static volatile int init_done = 0;
502263fc984bdc858ee931d3e35c87c404de923950Johann
517bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (!init_done) {
527bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vpx_dsp_rtcd();
537bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_init_intra_predictors();
547bc9febe8749e98a3812a0dc4380ceae75c29450Johann    init_done = 1;
557bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
562263fc984bdc858ee931d3e35c87c404de923950Johann}
572263fc984bdc858ee931d3e35c87c404de923950Johann
587bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void remove_decompressor(VP8D_COMP *pbi) {
59ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if CONFIG_ERROR_CONCEALMENT
607bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_de_alloc_overlap_lists(pbi);
61ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
627bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_remove_common(&pbi->common);
637bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vpx_free(pbi);
64ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
65ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
667bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic struct VP8D_COMP *create_decompressor(VP8D_CONFIG *oxcf) {
677bc9febe8749e98a3812a0dc4380ceae75c29450Johann  VP8D_COMP *pbi = vpx_memalign(32, sizeof(VP8D_COMP));
681b362b15af34006e6a11974088a46d42b903418eJohann
697bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (!pbi) return NULL;
701b362b15af34006e6a11974088a46d42b903418eJohann
717bc9febe8749e98a3812a0dc4380ceae75c29450Johann  memset(pbi, 0, sizeof(VP8D_COMP));
721b362b15af34006e6a11974088a46d42b903418eJohann
737bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (setjmp(pbi->common.error.jmp)) {
747bc9febe8749e98a3812a0dc4380ceae75c29450Johann    pbi->common.error.setjmp = 0;
757bc9febe8749e98a3812a0dc4380ceae75c29450Johann    remove_decompressor(pbi);
767bc9febe8749e98a3812a0dc4380ceae75c29450Johann    return 0;
777bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
781b362b15af34006e6a11974088a46d42b903418eJohann
797bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pbi->common.error.setjmp = 1;
801b362b15af34006e6a11974088a46d42b903418eJohann
817bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_create_common(&pbi->common);
821b362b15af34006e6a11974088a46d42b903418eJohann
837bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pbi->common.current_video_frame = 0;
847bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pbi->ready_for_new_data = 1;
851b362b15af34006e6a11974088a46d42b903418eJohann
867bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* vp8cx_init_de_quantizer() is first called here. Add check in
877bc9febe8749e98a3812a0dc4380ceae75c29450Johann   * frame_init_dequantizer() to avoid
887bc9febe8749e98a3812a0dc4380ceae75c29450Johann   *  unnecessary calling of vp8cx_init_de_quantizer() for every frame.
897bc9febe8749e98a3812a0dc4380ceae75c29450Johann   */
907bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8cx_init_de_quantizer(pbi);
911b362b15af34006e6a11974088a46d42b903418eJohann
927bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_loop_filter_init(&pbi->common);
931b362b15af34006e6a11974088a46d42b903418eJohann
947bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pbi->common.error.setjmp = 0;
951b362b15af34006e6a11974088a46d42b903418eJohann
961b362b15af34006e6a11974088a46d42b903418eJohann#if CONFIG_ERROR_CONCEALMENT
977bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pbi->ec_enabled = oxcf->error_concealment;
987bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pbi->overlaps = NULL;
991b362b15af34006e6a11974088a46d42b903418eJohann#else
1007bc9febe8749e98a3812a0dc4380ceae75c29450Johann  (void)oxcf;
1017bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pbi->ec_enabled = 0;
1021b362b15af34006e6a11974088a46d42b903418eJohann#endif
1037bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* Error concealment is activated after a key frame has been
1047bc9febe8749e98a3812a0dc4380ceae75c29450Johann   * decoded without errors when error concealment is enabled.
1057bc9febe8749e98a3812a0dc4380ceae75c29450Johann   */
1067bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pbi->ec_active = 0;
1071b362b15af34006e6a11974088a46d42b903418eJohann
1087bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pbi->decoded_key_frame = 0;
1091b362b15af34006e6a11974088a46d42b903418eJohann
1107bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* Independent partitions is activated when a frame updates the
1117bc9febe8749e98a3812a0dc4380ceae75c29450Johann   * token probability table to have equal probabilities over the
1127bc9febe8749e98a3812a0dc4380ceae75c29450Johann   * PREV_COEF context.
1137bc9febe8749e98a3812a0dc4380ceae75c29450Johann   */
1147bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pbi->independent_partitions = 0;
1151b362b15af34006e6a11974088a46d42b903418eJohann
1167bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_setup_block_dptrs(&pbi->mb);
1171b362b15af34006e6a11974088a46d42b903418eJohann
1187bc9febe8749e98a3812a0dc4380ceae75c29450Johann  once(initialize_dec);
1192263fc984bdc858ee931d3e35c87c404de923950Johann
1207bc9febe8749e98a3812a0dc4380ceae75c29450Johann  return pbi;
1211b362b15af34006e6a11974088a46d42b903418eJohann}
1221b362b15af34006e6a11974088a46d42b903418eJohann
1237bc9febe8749e98a3812a0dc4380ceae75c29450Johannvpx_codec_err_t vp8dx_get_reference(VP8D_COMP *pbi,
1247bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                    enum vpx_ref_frame_type ref_frame_flag,
1257bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                    YV12_BUFFER_CONFIG *sd) {
1267bc9febe8749e98a3812a0dc4380ceae75c29450Johann  VP8_COMMON *cm = &pbi->common;
1277bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int ref_fb_idx;
1287bc9febe8749e98a3812a0dc4380ceae75c29450Johann
1297bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (ref_frame_flag == VP8_LAST_FRAME) {
1307bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ref_fb_idx = cm->lst_fb_idx;
1317bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } else if (ref_frame_flag == VP8_GOLD_FRAME) {
1327bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ref_fb_idx = cm->gld_fb_idx;
1337bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } else if (ref_frame_flag == VP8_ALTR_FRAME) {
1347bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ref_fb_idx = cm->alt_fb_idx;
1357bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } else {
1367bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
1377bc9febe8749e98a3812a0dc4380ceae75c29450Johann                       "Invalid reference frame");
1381b362b15af34006e6a11974088a46d42b903418eJohann    return pbi->common.error.error_code;
1397bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
1407bc9febe8749e98a3812a0dc4380ceae75c29450Johann
1417bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (cm->yv12_fb[ref_fb_idx].y_height != sd->y_height ||
1427bc9febe8749e98a3812a0dc4380ceae75c29450Johann      cm->yv12_fb[ref_fb_idx].y_width != sd->y_width ||
1437bc9febe8749e98a3812a0dc4380ceae75c29450Johann      cm->yv12_fb[ref_fb_idx].uv_height != sd->uv_height ||
1447bc9febe8749e98a3812a0dc4380ceae75c29450Johann      cm->yv12_fb[ref_fb_idx].uv_width != sd->uv_width) {
1457bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
1467bc9febe8749e98a3812a0dc4380ceae75c29450Johann                       "Incorrect buffer dimensions");
1477bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } else
1487bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_yv12_copy_frame(&cm->yv12_fb[ref_fb_idx], sd);
1497bc9febe8749e98a3812a0dc4380ceae75c29450Johann
1507bc9febe8749e98a3812a0dc4380ceae75c29450Johann  return pbi->common.error.error_code;
1511b362b15af34006e6a11974088a46d42b903418eJohann}
1521b362b15af34006e6a11974088a46d42b903418eJohann
1537bc9febe8749e98a3812a0dc4380ceae75c29450Johannvpx_codec_err_t vp8dx_set_reference(VP8D_COMP *pbi,
1547bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                    enum vpx_ref_frame_type ref_frame_flag,
1557bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                    YV12_BUFFER_CONFIG *sd) {
1567bc9febe8749e98a3812a0dc4380ceae75c29450Johann  VP8_COMMON *cm = &pbi->common;
1577bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int *ref_fb_ptr = NULL;
1587bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int free_fb;
1597bc9febe8749e98a3812a0dc4380ceae75c29450Johann
1607bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (ref_frame_flag == VP8_LAST_FRAME) {
1617bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ref_fb_ptr = &cm->lst_fb_idx;
1627bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } else if (ref_frame_flag == VP8_GOLD_FRAME) {
1637bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ref_fb_ptr = &cm->gld_fb_idx;
1647bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } else if (ref_frame_flag == VP8_ALTR_FRAME) {
1657bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ref_fb_ptr = &cm->alt_fb_idx;
1667bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } else {
1677bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
1687bc9febe8749e98a3812a0dc4380ceae75c29450Johann                       "Invalid reference frame");
1697bc9febe8749e98a3812a0dc4380ceae75c29450Johann    return pbi->common.error.error_code;
1707bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
1717bc9febe8749e98a3812a0dc4380ceae75c29450Johann
1727bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (cm->yv12_fb[*ref_fb_ptr].y_height != sd->y_height ||
1737bc9febe8749e98a3812a0dc4380ceae75c29450Johann      cm->yv12_fb[*ref_fb_ptr].y_width != sd->y_width ||
1747bc9febe8749e98a3812a0dc4380ceae75c29450Johann      cm->yv12_fb[*ref_fb_ptr].uv_height != sd->uv_height ||
1757bc9febe8749e98a3812a0dc4380ceae75c29450Johann      cm->yv12_fb[*ref_fb_ptr].uv_width != sd->uv_width) {
1767bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
1777bc9febe8749e98a3812a0dc4380ceae75c29450Johann                       "Incorrect buffer dimensions");
1787bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } else {
1797bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* Find an empty frame buffer. */
1807bc9febe8749e98a3812a0dc4380ceae75c29450Johann    free_fb = get_free_fb(cm);
1817bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* Decrease fb_idx_ref_cnt since it will be increased again in
1827bc9febe8749e98a3812a0dc4380ceae75c29450Johann     * ref_cnt_fb() below. */
1837bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cm->fb_idx_ref_cnt[free_fb]--;
1847bc9febe8749e98a3812a0dc4380ceae75c29450Johann
1857bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* Manage the reference counters and copy image. */
1867bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ref_cnt_fb(cm->fb_idx_ref_cnt, ref_fb_ptr, free_fb);
1877bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_yv12_copy_frame(sd, &cm->yv12_fb[*ref_fb_ptr]);
1887bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
1897bc9febe8749e98a3812a0dc4380ceae75c29450Johann
1907bc9febe8749e98a3812a0dc4380ceae75c29450Johann  return pbi->common.error.error_code;
1911b362b15af34006e6a11974088a46d42b903418eJohann}
1921b362b15af34006e6a11974088a46d42b903418eJohann
1937bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic int get_free_fb(VP8_COMMON *cm) {
1947bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int i;
1957bc9febe8749e98a3812a0dc4380ceae75c29450Johann  for (i = 0; i < NUM_YV12_BUFFERS; ++i) {
1967bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (cm->fb_idx_ref_cnt[i] == 0) break;
1977bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
1981b362b15af34006e6a11974088a46d42b903418eJohann
1997bc9febe8749e98a3812a0dc4380ceae75c29450Johann  assert(i < NUM_YV12_BUFFERS);
2007bc9febe8749e98a3812a0dc4380ceae75c29450Johann  cm->fb_idx_ref_cnt[i] = 1;
2017bc9febe8749e98a3812a0dc4380ceae75c29450Johann  return i;
2021b362b15af34006e6a11974088a46d42b903418eJohann}
2031b362b15af34006e6a11974088a46d42b903418eJohann
2047bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void ref_cnt_fb(int *buf, int *idx, int new_idx) {
2057bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (buf[*idx] > 0) buf[*idx]--;
2061b362b15af34006e6a11974088a46d42b903418eJohann
2077bc9febe8749e98a3812a0dc4380ceae75c29450Johann  *idx = new_idx;
2081b362b15af34006e6a11974088a46d42b903418eJohann
2097bc9febe8749e98a3812a0dc4380ceae75c29450Johann  buf[new_idx]++;
2101b362b15af34006e6a11974088a46d42b903418eJohann}
2111b362b15af34006e6a11974088a46d42b903418eJohann
2121b362b15af34006e6a11974088a46d42b903418eJohann/* If any buffer copy / swapping is signalled it should be done here. */
2137bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic int swap_frame_buffers(VP8_COMMON *cm) {
2147bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int err = 0;
2157bc9febe8749e98a3812a0dc4380ceae75c29450Johann
2167bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* The alternate reference frame or golden frame can be updated
2177bc9febe8749e98a3812a0dc4380ceae75c29450Johann   *  using the new, last, or golden/alt ref frame.  If it
2187bc9febe8749e98a3812a0dc4380ceae75c29450Johann   *  is updated using the newly decoded frame it is a refresh.
2197bc9febe8749e98a3812a0dc4380ceae75c29450Johann   *  An update using the last or golden/alt ref frame is a copy.
2207bc9febe8749e98a3812a0dc4380ceae75c29450Johann   */
2217bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (cm->copy_buffer_to_arf) {
2227bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int new_fb = 0;
2237bc9febe8749e98a3812a0dc4380ceae75c29450Johann
2247bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (cm->copy_buffer_to_arf == 1) {
2257bc9febe8749e98a3812a0dc4380ceae75c29450Johann      new_fb = cm->lst_fb_idx;
2267bc9febe8749e98a3812a0dc4380ceae75c29450Johann    } else if (cm->copy_buffer_to_arf == 2) {
2277bc9febe8749e98a3812a0dc4380ceae75c29450Johann      new_fb = cm->gld_fb_idx;
2287bc9febe8749e98a3812a0dc4380ceae75c29450Johann    } else {
2297bc9febe8749e98a3812a0dc4380ceae75c29450Johann      err = -1;
2301b362b15af34006e6a11974088a46d42b903418eJohann    }
2311b362b15af34006e6a11974088a46d42b903418eJohann
2327bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->alt_fb_idx, new_fb);
2337bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
2341b362b15af34006e6a11974088a46d42b903418eJohann
2357bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (cm->copy_buffer_to_gf) {
2367bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int new_fb = 0;
2371b362b15af34006e6a11974088a46d42b903418eJohann
2387bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (cm->copy_buffer_to_gf == 1) {
2397bc9febe8749e98a3812a0dc4380ceae75c29450Johann      new_fb = cm->lst_fb_idx;
2407bc9febe8749e98a3812a0dc4380ceae75c29450Johann    } else if (cm->copy_buffer_to_gf == 2) {
2417bc9febe8749e98a3812a0dc4380ceae75c29450Johann      new_fb = cm->alt_fb_idx;
2427bc9febe8749e98a3812a0dc4380ceae75c29450Johann    } else {
2437bc9febe8749e98a3812a0dc4380ceae75c29450Johann      err = -1;
2441b362b15af34006e6a11974088a46d42b903418eJohann    }
2451b362b15af34006e6a11974088a46d42b903418eJohann
2467bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->gld_fb_idx, new_fb);
2477bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
2481b362b15af34006e6a11974088a46d42b903418eJohann
2497bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (cm->refresh_golden_frame) {
2507bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->gld_fb_idx, cm->new_fb_idx);
2517bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
2521b362b15af34006e6a11974088a46d42b903418eJohann
2537bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (cm->refresh_alt_ref_frame) {
2547bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->alt_fb_idx, cm->new_fb_idx);
2557bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
2561b362b15af34006e6a11974088a46d42b903418eJohann
2577bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (cm->refresh_last_frame) {
2587bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->lst_fb_idx, cm->new_fb_idx);
2597bc9febe8749e98a3812a0dc4380ceae75c29450Johann
2607bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cm->frame_to_show = &cm->yv12_fb[cm->lst_fb_idx];
2617bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } else {
2627bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx];
2637bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
2641b362b15af34006e6a11974088a46d42b903418eJohann
2657bc9febe8749e98a3812a0dc4380ceae75c29450Johann  cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
2661b362b15af34006e6a11974088a46d42b903418eJohann
2677bc9febe8749e98a3812a0dc4380ceae75c29450Johann  return err;
2681b362b15af34006e6a11974088a46d42b903418eJohann}
2691b362b15af34006e6a11974088a46d42b903418eJohann
2707bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic int check_fragments_for_errors(VP8D_COMP *pbi) {
2717bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (!pbi->ec_active && pbi->fragments.count <= 1 &&
2727bc9febe8749e98a3812a0dc4380ceae75c29450Johann      pbi->fragments.sizes[0] == 0) {
2737bc9febe8749e98a3812a0dc4380ceae75c29450Johann    VP8_COMMON *cm = &pbi->common;
2747bc9febe8749e98a3812a0dc4380ceae75c29450Johann
2757bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* If error concealment is disabled we won't signal missing frames
2767bc9febe8749e98a3812a0dc4380ceae75c29450Johann     * to the decoder.
2777bc9febe8749e98a3812a0dc4380ceae75c29450Johann     */
2787bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (cm->fb_idx_ref_cnt[cm->lst_fb_idx] > 1) {
2797bc9febe8749e98a3812a0dc4380ceae75c29450Johann      /* The last reference shares buffer with another reference
2807bc9febe8749e98a3812a0dc4380ceae75c29450Johann       * buffer. Move it to its own buffer before setting it as
2817bc9febe8749e98a3812a0dc4380ceae75c29450Johann       * corrupt, otherwise we will make multiple buffers corrupt.
2827bc9febe8749e98a3812a0dc4380ceae75c29450Johann       */
2837bc9febe8749e98a3812a0dc4380ceae75c29450Johann      const int prev_idx = cm->lst_fb_idx;
2847bc9febe8749e98a3812a0dc4380ceae75c29450Johann      cm->fb_idx_ref_cnt[prev_idx]--;
2857bc9febe8749e98a3812a0dc4380ceae75c29450Johann      cm->lst_fb_idx = get_free_fb(cm);
2867bc9febe8749e98a3812a0dc4380ceae75c29450Johann      vp8_yv12_copy_frame(&cm->yv12_fb[prev_idx], &cm->yv12_fb[cm->lst_fb_idx]);
2871b362b15af34006e6a11974088a46d42b903418eJohann    }
2887bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* This is used to signal that we are missing frames.
2897bc9febe8749e98a3812a0dc4380ceae75c29450Johann     * We do not know if the missing frame(s) was supposed to update
2907bc9febe8749e98a3812a0dc4380ceae75c29450Johann     * any of the reference buffers, but we act conservative and
2917bc9febe8749e98a3812a0dc4380ceae75c29450Johann     * mark only the last buffer as corrupted.
2927bc9febe8749e98a3812a0dc4380ceae75c29450Johann     */
2937bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
2947bc9febe8749e98a3812a0dc4380ceae75c29450Johann
2957bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* Signal that we have no frame to show. */
2967bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cm->show_frame = 0;
2977bc9febe8749e98a3812a0dc4380ceae75c29450Johann
2987bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* Nothing more to do. */
2997bc9febe8749e98a3812a0dc4380ceae75c29450Johann    return 0;
3007bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
3011b362b15af34006e6a11974088a46d42b903418eJohann
3027bc9febe8749e98a3812a0dc4380ceae75c29450Johann  return 1;
303ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
304ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
305ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangint vp8dx_receive_compressed_data(VP8D_COMP *pbi, size_t size,
3067bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                  const uint8_t *source, int64_t time_stamp) {
3077bc9febe8749e98a3812a0dc4380ceae75c29450Johann  VP8_COMMON *cm = &pbi->common;
3087bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int retcode = -1;
3097bc9febe8749e98a3812a0dc4380ceae75c29450Johann  (void)size;
3107bc9febe8749e98a3812a0dc4380ceae75c29450Johann  (void)source;
3111b362b15af34006e6a11974088a46d42b903418eJohann
3127bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pbi->common.error.error_code = VPX_CODEC_OK;
3131b362b15af34006e6a11974088a46d42b903418eJohann
3147bc9febe8749e98a3812a0dc4380ceae75c29450Johann  retcode = check_fragments_for_errors(pbi);
3157bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (retcode <= 0) return retcode;
3161b362b15af34006e6a11974088a46d42b903418eJohann
3177bc9febe8749e98a3812a0dc4380ceae75c29450Johann  cm->new_fb_idx = get_free_fb(cm);
3181b362b15af34006e6a11974088a46d42b903418eJohann
3197bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* setup reference frames for vp8_decode_frame */
3207bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pbi->dec_fb_ref[INTRA_FRAME] = &cm->yv12_fb[cm->new_fb_idx];
3217bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pbi->dec_fb_ref[LAST_FRAME] = &cm->yv12_fb[cm->lst_fb_idx];
3227bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pbi->dec_fb_ref[GOLDEN_FRAME] = &cm->yv12_fb[cm->gld_fb_idx];
3237bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pbi->dec_fb_ref[ALTREF_FRAME] = &cm->yv12_fb[cm->alt_fb_idx];
3241b362b15af34006e6a11974088a46d42b903418eJohann
3257bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (setjmp(pbi->common.error.jmp)) {
3267bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* We do not know if the missing frame(s) was supposed to update
3277bc9febe8749e98a3812a0dc4380ceae75c29450Johann     * any of the reference buffers, but we act conservative and
3287bc9febe8749e98a3812a0dc4380ceae75c29450Johann     * mark only the last buffer as corrupted.
3297bc9febe8749e98a3812a0dc4380ceae75c29450Johann     */
3307bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
3317bc9febe8749e98a3812a0dc4380ceae75c29450Johann
3327bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0) {
3337bc9febe8749e98a3812a0dc4380ceae75c29450Johann      cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
3341b362b15af34006e6a11974088a46d42b903418eJohann    }
3357bc9febe8749e98a3812a0dc4380ceae75c29450Johann    goto decode_exit;
3367bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
3371b362b15af34006e6a11974088a46d42b903418eJohann
3387bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pbi->common.error.setjmp = 1;
3391b362b15af34006e6a11974088a46d42b903418eJohann
3407bc9febe8749e98a3812a0dc4380ceae75c29450Johann  retcode = vp8_decode_frame(pbi);
3417bc9febe8749e98a3812a0dc4380ceae75c29450Johann
3427bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (retcode < 0) {
3437bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0) {
3447bc9febe8749e98a3812a0dc4380ceae75c29450Johann      cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
345ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
346ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3477bc9febe8749e98a3812a0dc4380ceae75c29450Johann    pbi->common.error.error_code = VPX_CODEC_ERROR;
3487bc9febe8749e98a3812a0dc4380ceae75c29450Johann    goto decode_exit;
3497bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
3507bc9febe8749e98a3812a0dc4380ceae75c29450Johann
3517bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (swap_frame_buffers(cm)) {
3527bc9febe8749e98a3812a0dc4380ceae75c29450Johann    pbi->common.error.error_code = VPX_CODEC_ERROR;
3537bc9febe8749e98a3812a0dc4380ceae75c29450Johann    goto decode_exit;
3547bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
3557bc9febe8749e98a3812a0dc4380ceae75c29450Johann
3567bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vpx_clear_system_state();
3577bc9febe8749e98a3812a0dc4380ceae75c29450Johann
3587bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (cm->show_frame) {
3597bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cm->current_video_frame++;
3607bc9febe8749e98a3812a0dc4380ceae75c29450Johann    cm->show_frame_mi = cm->mi;
3617bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
3627bc9febe8749e98a3812a0dc4380ceae75c29450Johann
3637bc9febe8749e98a3812a0dc4380ceae75c29450Johann#if CONFIG_ERROR_CONCEALMENT
3647bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* swap the mode infos to storage for future error concealment */
3657bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (pbi->ec_enabled && pbi->common.prev_mi) {
3667bc9febe8749e98a3812a0dc4380ceae75c29450Johann    MODE_INFO *tmp = pbi->common.prev_mi;
3677bc9febe8749e98a3812a0dc4380ceae75c29450Johann    int row, col;
3687bc9febe8749e98a3812a0dc4380ceae75c29450Johann    pbi->common.prev_mi = pbi->common.mi;
3697bc9febe8749e98a3812a0dc4380ceae75c29450Johann    pbi->common.mi = tmp;
3707bc9febe8749e98a3812a0dc4380ceae75c29450Johann
3717bc9febe8749e98a3812a0dc4380ceae75c29450Johann    /* Propagate the segment_ids to the next frame */
3727bc9febe8749e98a3812a0dc4380ceae75c29450Johann    for (row = 0; row < pbi->common.mb_rows; ++row) {
3737bc9febe8749e98a3812a0dc4380ceae75c29450Johann      for (col = 0; col < pbi->common.mb_cols; ++col) {
3747bc9febe8749e98a3812a0dc4380ceae75c29450Johann        const int i = row * pbi->common.mode_info_stride + col;
3757bc9febe8749e98a3812a0dc4380ceae75c29450Johann        pbi->common.mi[i].mbmi.segment_id =
3767bc9febe8749e98a3812a0dc4380ceae75c29450Johann            pbi->common.prev_mi[i].mbmi.segment_id;
3777bc9febe8749e98a3812a0dc4380ceae75c29450Johann      }
3781b362b15af34006e6a11974088a46d42b903418eJohann    }
3797bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
3801b362b15af34006e6a11974088a46d42b903418eJohann#endif
3811b362b15af34006e6a11974088a46d42b903418eJohann
3827bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pbi->ready_for_new_data = 0;
3837bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pbi->last_time_stamp = time_stamp;
3841b362b15af34006e6a11974088a46d42b903418eJohann
3851b362b15af34006e6a11974088a46d42b903418eJohanndecode_exit:
3867bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pbi->common.error.setjmp = 0;
3877bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vpx_clear_system_state();
3887bc9febe8749e98a3812a0dc4380ceae75c29450Johann  return retcode;
3891b362b15af34006e6a11974088a46d42b903418eJohann}
3907bc9febe8749e98a3812a0dc4380ceae75c29450Johannint vp8dx_get_raw_frame(VP8D_COMP *pbi, YV12_BUFFER_CONFIG *sd,
3917bc9febe8749e98a3812a0dc4380ceae75c29450Johann                        int64_t *time_stamp, int64_t *time_end_stamp,
3927bc9febe8749e98a3812a0dc4380ceae75c29450Johann                        vp8_ppflags_t *flags) {
3937bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int ret = -1;
3941b362b15af34006e6a11974088a46d42b903418eJohann
3957bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (pbi->ready_for_new_data == 1) return ret;
3961b362b15af34006e6a11974088a46d42b903418eJohann
3977bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* ie no raw frame to show!!! */
3987bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (pbi->common.show_frame == 0) return ret;
3991b362b15af34006e6a11974088a46d42b903418eJohann
4007bc9febe8749e98a3812a0dc4380ceae75c29450Johann  pbi->ready_for_new_data = 1;
4017bc9febe8749e98a3812a0dc4380ceae75c29450Johann  *time_stamp = pbi->last_time_stamp;
4027bc9febe8749e98a3812a0dc4380ceae75c29450Johann  *time_end_stamp = 0;
4031b362b15af34006e6a11974088a46d42b903418eJohann
4041b362b15af34006e6a11974088a46d42b903418eJohann#if CONFIG_POSTPROC
4057bc9febe8749e98a3812a0dc4380ceae75c29450Johann  ret = vp8_post_proc_frame(&pbi->common, sd, flags);
4061b362b15af34006e6a11974088a46d42b903418eJohann#else
4077bc9febe8749e98a3812a0dc4380ceae75c29450Johann  (void)flags;
4087bc9febe8749e98a3812a0dc4380ceae75c29450Johann
4097bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (pbi->common.frame_to_show) {
4107bc9febe8749e98a3812a0dc4380ceae75c29450Johann    *sd = *pbi->common.frame_to_show;
4117bc9febe8749e98a3812a0dc4380ceae75c29450Johann    sd->y_width = pbi->common.Width;
4127bc9febe8749e98a3812a0dc4380ceae75c29450Johann    sd->y_height = pbi->common.Height;
4137bc9febe8749e98a3812a0dc4380ceae75c29450Johann    sd->uv_height = pbi->common.Height / 2;
4147bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ret = 0;
4157bc9febe8749e98a3812a0dc4380ceae75c29450Johann  } else {
4167bc9febe8749e98a3812a0dc4380ceae75c29450Johann    ret = -1;
4177bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
4181b362b15af34006e6a11974088a46d42b903418eJohann
4191b362b15af34006e6a11974088a46d42b903418eJohann#endif /*!CONFIG_POSTPROC*/
4207bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vpx_clear_system_state();
4217bc9febe8749e98a3812a0dc4380ceae75c29450Johann  return ret;
4221b362b15af34006e6a11974088a46d42b903418eJohann}
4231b362b15af34006e6a11974088a46d42b903418eJohann
4241b362b15af34006e6a11974088a46d42b903418eJohann/* This function as written isn't decoder specific, but the encoder has
4251b362b15af34006e6a11974088a46d42b903418eJohann * much faster ways of computing this, so it's ok for it to live in a
4261b362b15af34006e6a11974088a46d42b903418eJohann * decode specific file.
4271b362b15af34006e6a11974088a46d42b903418eJohann */
4287bc9febe8749e98a3812a0dc4380ceae75c29450Johannint vp8dx_references_buffer(VP8_COMMON *oci, int ref_frame) {
4297bc9febe8749e98a3812a0dc4380ceae75c29450Johann  const MODE_INFO *mi = oci->mi;
4307bc9febe8749e98a3812a0dc4380ceae75c29450Johann  int mb_row, mb_col;
4311b362b15af34006e6a11974088a46d42b903418eJohann
4327bc9febe8749e98a3812a0dc4380ceae75c29450Johann  for (mb_row = 0; mb_row < oci->mb_rows; ++mb_row) {
4337bc9febe8749e98a3812a0dc4380ceae75c29450Johann    for (mb_col = 0; mb_col < oci->mb_cols; mb_col++, mi++) {
4347bc9febe8749e98a3812a0dc4380ceae75c29450Johann      if (mi->mbmi.ref_frame == ref_frame) return 1;
4357bc9febe8749e98a3812a0dc4380ceae75c29450Johann    }
4367bc9febe8749e98a3812a0dc4380ceae75c29450Johann    mi++;
4377bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
4387bc9febe8749e98a3812a0dc4380ceae75c29450Johann  return 0;
4391b362b15af34006e6a11974088a46d42b903418eJohann}
440ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4417bc9febe8749e98a3812a0dc4380ceae75c29450Johannint vp8_create_decoder_instances(struct frame_buffers *fb, VP8D_CONFIG *oxcf) {
4427bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* decoder instance for single thread mode */
4437bc9febe8749e98a3812a0dc4380ceae75c29450Johann  fb->pbi[0] = create_decompressor(oxcf);
4447bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (!fb->pbi[0]) return VPX_CODEC_ERROR;
445ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
446ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if CONFIG_MULTITHREAD
4477bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (setjmp(fb->pbi[0]->common.error.jmp)) {
4487bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vp8_remove_decoder_instances(fb);
4498b92989c89bec8632aa47dc58dc162f199d62edcJames Zern    memset(fb->pbi, 0, sizeof(fb->pbi));
4507bc9febe8749e98a3812a0dc4380ceae75c29450Johann    vpx_clear_system_state();
4517bc9febe8749e98a3812a0dc4380ceae75c29450Johann    return VPX_CODEC_ERROR;
4527bc9febe8749e98a3812a0dc4380ceae75c29450Johann  }
4537bc9febe8749e98a3812a0dc4380ceae75c29450Johann
4547bc9febe8749e98a3812a0dc4380ceae75c29450Johann  fb->pbi[0]->common.error.setjmp = 1;
4557bc9febe8749e98a3812a0dc4380ceae75c29450Johann  fb->pbi[0]->max_threads = oxcf->max_threads;
4567bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_decoder_create_threads(fb->pbi[0]);
4577bc9febe8749e98a3812a0dc4380ceae75c29450Johann  fb->pbi[0]->common.error.setjmp = 0;
458ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
4597bc9febe8749e98a3812a0dc4380ceae75c29450Johann  return VPX_CODEC_OK;
460ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
461ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4627bc9febe8749e98a3812a0dc4380ceae75c29450Johannint vp8_remove_decoder_instances(struct frame_buffers *fb) {
4637bc9febe8749e98a3812a0dc4380ceae75c29450Johann  VP8D_COMP *pbi = fb->pbi[0];
464ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4657bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (!pbi) return VPX_CODEC_ERROR;
466ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if CONFIG_MULTITHREAD
4677bc9febe8749e98a3812a0dc4380ceae75c29450Johann  vp8_decoder_remove_threads(pbi);
468ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
469ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
4707bc9febe8749e98a3812a0dc4380ceae75c29450Johann  /* decoder instance for single thread mode */
4717bc9febe8749e98a3812a0dc4380ceae75c29450Johann  remove_decompressor(pbi);
4727bc9febe8749e98a3812a0dc4380ceae75c29450Johann  return VPX_CODEC_OK;
473ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
4748b92989c89bec8632aa47dc58dc162f199d62edcJames Zern
4758b92989c89bec8632aa47dc58dc162f199d62edcJames Zernint vp8dx_get_quantizer(const VP8D_COMP *cpi) {
4768b92989c89bec8632aa47dc58dc162f199d62edcJames Zern  return cpi->common.base_qindex;
4778b92989c89bec8632aa47dc58dc162f199d62edcJames Zern}
478