media/libvpx/vp8/decoder/onyxd_if.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /*
michael@0 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license
michael@0 5 * that can be found in the LICENSE file in the root of the source
michael@0 6 * tree. An additional intellectual property rights grant can be found
michael@0 7 * in the file PATENTS. All contributing project authors may
michael@0 8 * be found in the AUTHORS file in the root of the source tree.
michael@0 9 */
michael@0 10
michael@0 11
michael@0 12 #include "vp8/common/onyxc_int.h"
michael@0 13 #if CONFIG_POSTPROC
michael@0 14 #include "vp8/common/postproc.h"
michael@0 15 #endif
michael@0 16 #include "vp8/common/onyxd.h"
michael@0 17 #include "onyxd_int.h"
michael@0 18 #include "vpx_mem/vpx_mem.h"
michael@0 19 #include "vp8/common/alloccommon.h"
michael@0 20 #include "vp8/common/loopfilter.h"
michael@0 21 #include "vp8/common/swapyv12buffer.h"
michael@0 22 #include "vp8/common/threading.h"
michael@0 23 #include "decoderthreading.h"
michael@0 24 #include <stdio.h>
michael@0 25 #include <assert.h>
michael@0 26
michael@0 27 #include "vp8/common/quant_common.h"
michael@0 28 #include "./vpx_scale_rtcd.h"
michael@0 29 #include "vpx_scale/vpx_scale.h"
michael@0 30 #include "vp8/common/systemdependent.h"
michael@0 31 #include "vpx_ports/vpx_timer.h"
michael@0 32 #include "detokenize.h"
michael@0 33 #if CONFIG_ERROR_CONCEALMENT
michael@0 34 #include "error_concealment.h"
michael@0 35 #endif
michael@0 36 #if ARCH_ARM
michael@0 37 #include "vpx_ports/arm.h"
michael@0 38 #endif
michael@0 39
michael@0 40 extern void vp8_init_loop_filter(VP8_COMMON *cm);
michael@0 41 extern void vp8cx_init_de_quantizer(VP8D_COMP *pbi);
michael@0 42 static int get_free_fb (VP8_COMMON *cm);
michael@0 43 static void ref_cnt_fb (int *buf, int *idx, int new_idx);
michael@0 44
michael@0 45 static void remove_decompressor(VP8D_COMP *pbi)
michael@0 46 {
michael@0 47 #if CONFIG_ERROR_CONCEALMENT
michael@0 48 vp8_de_alloc_overlap_lists(pbi);
michael@0 49 #endif
michael@0 50 vp8_remove_common(&pbi->common);
michael@0 51 vpx_free(pbi);
michael@0 52 }
michael@0 53
michael@0 54 static struct VP8D_COMP * create_decompressor(VP8D_CONFIG *oxcf)
michael@0 55 {
michael@0 56 VP8D_COMP *pbi = vpx_memalign(32, sizeof(VP8D_COMP));
michael@0 57
michael@0 58 if (!pbi)
michael@0 59 return NULL;
michael@0 60
michael@0 61 vpx_memset(pbi, 0, sizeof(VP8D_COMP));
michael@0 62
michael@0 63 if (setjmp(pbi->common.error.jmp))
michael@0 64 {
michael@0 65 pbi->common.error.setjmp = 0;
michael@0 66 remove_decompressor(pbi);
michael@0 67 return 0;
michael@0 68 }
michael@0 69
michael@0 70 pbi->common.error.setjmp = 1;
michael@0 71
michael@0 72 vp8_create_common(&pbi->common);
michael@0 73
michael@0 74 pbi->common.current_video_frame = 0;
michael@0 75 pbi->ready_for_new_data = 1;
michael@0 76
michael@0 77 /* vp8cx_init_de_quantizer() is first called here. Add check in frame_init_dequantizer() to avoid
michael@0 78 * unnecessary calling of vp8cx_init_de_quantizer() for every frame.
michael@0 79 */
michael@0 80 vp8cx_init_de_quantizer(pbi);
michael@0 81
michael@0 82 vp8_loop_filter_init(&pbi->common);
michael@0 83
michael@0 84 pbi->common.error.setjmp = 0;
michael@0 85
michael@0 86 #if CONFIG_ERROR_CONCEALMENT
michael@0 87 pbi->ec_enabled = oxcf->error_concealment;
michael@0 88 pbi->overlaps = NULL;
michael@0 89 #else
michael@0 90 pbi->ec_enabled = 0;
michael@0 91 #endif
michael@0 92 /* Error concealment is activated after a key frame has been
michael@0 93 * decoded without errors when error concealment is enabled.
michael@0 94 */
michael@0 95 pbi->ec_active = 0;
michael@0 96
michael@0 97 pbi->decoded_key_frame = 0;
michael@0 98
michael@0 99 /* Independent partitions is activated when a frame updates the
michael@0 100 * token probability table to have equal probabilities over the
michael@0 101 * PREV_COEF context.
michael@0 102 */
michael@0 103 pbi->independent_partitions = 0;
michael@0 104
michael@0 105 vp8_setup_block_dptrs(&pbi->mb);
michael@0 106
michael@0 107 return pbi;
michael@0 108 }
michael@0 109
michael@0 110 vpx_codec_err_t vp8dx_get_reference(VP8D_COMP *pbi, enum vpx_ref_frame_type ref_frame_flag, YV12_BUFFER_CONFIG *sd)
michael@0 111 {
michael@0 112 VP8_COMMON *cm = &pbi->common;
michael@0 113 int ref_fb_idx;
michael@0 114
michael@0 115 if (ref_frame_flag == VP8_LAST_FRAME)
michael@0 116 ref_fb_idx = cm->lst_fb_idx;
michael@0 117 else if (ref_frame_flag == VP8_GOLD_FRAME)
michael@0 118 ref_fb_idx = cm->gld_fb_idx;
michael@0 119 else if (ref_frame_flag == VP8_ALTR_FRAME)
michael@0 120 ref_fb_idx = cm->alt_fb_idx;
michael@0 121 else{
michael@0 122 vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
michael@0 123 "Invalid reference frame");
michael@0 124 return pbi->common.error.error_code;
michael@0 125 }
michael@0 126
michael@0 127 if(cm->yv12_fb[ref_fb_idx].y_height != sd->y_height ||
michael@0 128 cm->yv12_fb[ref_fb_idx].y_width != sd->y_width ||
michael@0 129 cm->yv12_fb[ref_fb_idx].uv_height != sd->uv_height ||
michael@0 130 cm->yv12_fb[ref_fb_idx].uv_width != sd->uv_width){
michael@0 131 vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
michael@0 132 "Incorrect buffer dimensions");
michael@0 133 }
michael@0 134 else
michael@0 135 vp8_yv12_copy_frame(&cm->yv12_fb[ref_fb_idx], sd);
michael@0 136
michael@0 137 return pbi->common.error.error_code;
michael@0 138 }
michael@0 139
michael@0 140
michael@0 141 vpx_codec_err_t vp8dx_set_reference(VP8D_COMP *pbi, enum vpx_ref_frame_type ref_frame_flag, YV12_BUFFER_CONFIG *sd)
michael@0 142 {
michael@0 143 VP8_COMMON *cm = &pbi->common;
michael@0 144 int *ref_fb_ptr = NULL;
michael@0 145 int free_fb;
michael@0 146
michael@0 147 if (ref_frame_flag == VP8_LAST_FRAME)
michael@0 148 ref_fb_ptr = &cm->lst_fb_idx;
michael@0 149 else if (ref_frame_flag == VP8_GOLD_FRAME)
michael@0 150 ref_fb_ptr = &cm->gld_fb_idx;
michael@0 151 else if (ref_frame_flag == VP8_ALTR_FRAME)
michael@0 152 ref_fb_ptr = &cm->alt_fb_idx;
michael@0 153 else{
michael@0 154 vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
michael@0 155 "Invalid reference frame");
michael@0 156 return pbi->common.error.error_code;
michael@0 157 }
michael@0 158
michael@0 159 if(cm->yv12_fb[*ref_fb_ptr].y_height != sd->y_height ||
michael@0 160 cm->yv12_fb[*ref_fb_ptr].y_width != sd->y_width ||
michael@0 161 cm->yv12_fb[*ref_fb_ptr].uv_height != sd->uv_height ||
michael@0 162 cm->yv12_fb[*ref_fb_ptr].uv_width != sd->uv_width){
michael@0 163 vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
michael@0 164 "Incorrect buffer dimensions");
michael@0 165 }
michael@0 166 else{
michael@0 167 /* Find an empty frame buffer. */
michael@0 168 free_fb = get_free_fb(cm);
michael@0 169 /* Decrease fb_idx_ref_cnt since it will be increased again in
michael@0 170 * ref_cnt_fb() below. */
michael@0 171 cm->fb_idx_ref_cnt[free_fb]--;
michael@0 172
michael@0 173 /* Manage the reference counters and copy image. */
michael@0 174 ref_cnt_fb (cm->fb_idx_ref_cnt, ref_fb_ptr, free_fb);
michael@0 175 vp8_yv12_copy_frame(sd, &cm->yv12_fb[*ref_fb_ptr]);
michael@0 176 }
michael@0 177
michael@0 178 return pbi->common.error.error_code;
michael@0 179 }
michael@0 180
michael@0 181 /*For ARM NEON, d8-d15 are callee-saved registers, and need to be saved by us.*/
michael@0 182 #if HAVE_NEON
michael@0 183 extern void vp8_push_neon(int64_t *store);
michael@0 184 extern void vp8_pop_neon(int64_t *store);
michael@0 185 #endif
michael@0 186
michael@0 187 static int get_free_fb (VP8_COMMON *cm)
michael@0 188 {
michael@0 189 int i;
michael@0 190 for (i = 0; i < NUM_YV12_BUFFERS; i++)
michael@0 191 if (cm->fb_idx_ref_cnt[i] == 0)
michael@0 192 break;
michael@0 193
michael@0 194 assert(i < NUM_YV12_BUFFERS);
michael@0 195 cm->fb_idx_ref_cnt[i] = 1;
michael@0 196 return i;
michael@0 197 }
michael@0 198
michael@0 199 static void ref_cnt_fb (int *buf, int *idx, int new_idx)
michael@0 200 {
michael@0 201 if (buf[*idx] > 0)
michael@0 202 buf[*idx]--;
michael@0 203
michael@0 204 *idx = new_idx;
michael@0 205
michael@0 206 buf[new_idx]++;
michael@0 207 }
michael@0 208
michael@0 209 /* If any buffer copy / swapping is signalled it should be done here. */
michael@0 210 static int swap_frame_buffers (VP8_COMMON *cm)
michael@0 211 {
michael@0 212 int err = 0;
michael@0 213
michael@0 214 /* The alternate reference frame or golden frame can be updated
michael@0 215 * using the new, last, or golden/alt ref frame. If it
michael@0 216 * is updated using the newly decoded frame it is a refresh.
michael@0 217 * An update using the last or golden/alt ref frame is a copy.
michael@0 218 */
michael@0 219 if (cm->copy_buffer_to_arf)
michael@0 220 {
michael@0 221 int new_fb = 0;
michael@0 222
michael@0 223 if (cm->copy_buffer_to_arf == 1)
michael@0 224 new_fb = cm->lst_fb_idx;
michael@0 225 else if (cm->copy_buffer_to_arf == 2)
michael@0 226 new_fb = cm->gld_fb_idx;
michael@0 227 else
michael@0 228 err = -1;
michael@0 229
michael@0 230 ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->alt_fb_idx, new_fb);
michael@0 231 }
michael@0 232
michael@0 233 if (cm->copy_buffer_to_gf)
michael@0 234 {
michael@0 235 int new_fb = 0;
michael@0 236
michael@0 237 if (cm->copy_buffer_to_gf == 1)
michael@0 238 new_fb = cm->lst_fb_idx;
michael@0 239 else if (cm->copy_buffer_to_gf == 2)
michael@0 240 new_fb = cm->alt_fb_idx;
michael@0 241 else
michael@0 242 err = -1;
michael@0 243
michael@0 244 ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->gld_fb_idx, new_fb);
michael@0 245 }
michael@0 246
michael@0 247 if (cm->refresh_golden_frame)
michael@0 248 ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->gld_fb_idx, cm->new_fb_idx);
michael@0 249
michael@0 250 if (cm->refresh_alt_ref_frame)
michael@0 251 ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->alt_fb_idx, cm->new_fb_idx);
michael@0 252
michael@0 253 if (cm->refresh_last_frame)
michael@0 254 {
michael@0 255 ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->lst_fb_idx, cm->new_fb_idx);
michael@0 256
michael@0 257 cm->frame_to_show = &cm->yv12_fb[cm->lst_fb_idx];
michael@0 258 }
michael@0 259 else
michael@0 260 cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx];
michael@0 261
michael@0 262 cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
michael@0 263
michael@0 264 return err;
michael@0 265 }
michael@0 266
michael@0 267 int check_fragments_for_errors(VP8D_COMP *pbi)
michael@0 268 {
michael@0 269 if (!pbi->ec_active &&
michael@0 270 pbi->fragments.count <= 1 && pbi->fragments.sizes[0] == 0)
michael@0 271 {
michael@0 272 VP8_COMMON *cm = &pbi->common;
michael@0 273
michael@0 274 /* If error concealment is disabled we won't signal missing frames
michael@0 275 * to the decoder.
michael@0 276 */
michael@0 277 if (cm->fb_idx_ref_cnt[cm->lst_fb_idx] > 1)
michael@0 278 {
michael@0 279 /* The last reference shares buffer with another reference
michael@0 280 * buffer. Move it to its own buffer before setting it as
michael@0 281 * corrupt, otherwise we will make multiple buffers corrupt.
michael@0 282 */
michael@0 283 const int prev_idx = cm->lst_fb_idx;
michael@0 284 cm->fb_idx_ref_cnt[prev_idx]--;
michael@0 285 cm->lst_fb_idx = get_free_fb(cm);
michael@0 286 vp8_yv12_copy_frame(&cm->yv12_fb[prev_idx],
michael@0 287 &cm->yv12_fb[cm->lst_fb_idx]);
michael@0 288 }
michael@0 289 /* This is used to signal that we are missing frames.
michael@0 290 * We do not know if the missing frame(s) was supposed to update
michael@0 291 * any of the reference buffers, but we act conservative and
michael@0 292 * mark only the last buffer as corrupted.
michael@0 293 */
michael@0 294 cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
michael@0 295
michael@0 296 /* Signal that we have no frame to show. */
michael@0 297 cm->show_frame = 0;
michael@0 298
michael@0 299 /* Nothing more to do. */
michael@0 300 return 0;
michael@0 301 }
michael@0 302
michael@0 303 return 1;
michael@0 304 }
michael@0 305
michael@0 306 int vp8dx_receive_compressed_data(VP8D_COMP *pbi, size_t size,
michael@0 307 const uint8_t *source,
michael@0 308 int64_t time_stamp)
michael@0 309 {
michael@0 310 #if HAVE_NEON
michael@0 311 int64_t dx_store_reg[8];
michael@0 312 #endif
michael@0 313 VP8_COMMON *cm = &pbi->common;
michael@0 314 int retcode = -1;
michael@0 315
michael@0 316 pbi->common.error.error_code = VPX_CODEC_OK;
michael@0 317
michael@0 318 retcode = check_fragments_for_errors(pbi);
michael@0 319 if(retcode <= 0)
michael@0 320 return retcode;
michael@0 321
michael@0 322 #if HAVE_NEON
michael@0 323 #if CONFIG_RUNTIME_CPU_DETECT
michael@0 324 if (cm->cpu_caps & HAS_NEON)
michael@0 325 #endif
michael@0 326 {
michael@0 327 vp8_push_neon(dx_store_reg);
michael@0 328 }
michael@0 329 #endif
michael@0 330
michael@0 331 cm->new_fb_idx = get_free_fb (cm);
michael@0 332
michael@0 333 /* setup reference frames for vp8_decode_frame */
michael@0 334 pbi->dec_fb_ref[INTRA_FRAME] = &cm->yv12_fb[cm->new_fb_idx];
michael@0 335 pbi->dec_fb_ref[LAST_FRAME] = &cm->yv12_fb[cm->lst_fb_idx];
michael@0 336 pbi->dec_fb_ref[GOLDEN_FRAME] = &cm->yv12_fb[cm->gld_fb_idx];
michael@0 337 pbi->dec_fb_ref[ALTREF_FRAME] = &cm->yv12_fb[cm->alt_fb_idx];
michael@0 338
michael@0 339 if (setjmp(pbi->common.error.jmp))
michael@0 340 {
michael@0 341 /* We do not know if the missing frame(s) was supposed to update
michael@0 342 * any of the reference buffers, but we act conservative and
michael@0 343 * mark only the last buffer as corrupted.
michael@0 344 */
michael@0 345 cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
michael@0 346
michael@0 347 if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
michael@0 348 cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
michael@0 349
michael@0 350 goto decode_exit;
michael@0 351 }
michael@0 352
michael@0 353 pbi->common.error.setjmp = 1;
michael@0 354
michael@0 355 retcode = vp8_decode_frame(pbi);
michael@0 356
michael@0 357 if (retcode < 0)
michael@0 358 {
michael@0 359 if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
michael@0 360 cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
michael@0 361
michael@0 362 pbi->common.error.error_code = VPX_CODEC_ERROR;
michael@0 363 goto decode_exit;
michael@0 364 }
michael@0 365
michael@0 366 if (swap_frame_buffers (cm))
michael@0 367 {
michael@0 368 pbi->common.error.error_code = VPX_CODEC_ERROR;
michael@0 369 goto decode_exit;
michael@0 370 }
michael@0 371
michael@0 372 vp8_clear_system_state();
michael@0 373
michael@0 374 if (cm->show_frame)
michael@0 375 {
michael@0 376 cm->current_video_frame++;
michael@0 377 cm->show_frame_mi = cm->mi;
michael@0 378 }
michael@0 379
michael@0 380 #if CONFIG_ERROR_CONCEALMENT
michael@0 381 /* swap the mode infos to storage for future error concealment */
michael@0 382 if (pbi->ec_enabled && pbi->common.prev_mi)
michael@0 383 {
michael@0 384 MODE_INFO* tmp = pbi->common.prev_mi;
michael@0 385 int row, col;
michael@0 386 pbi->common.prev_mi = pbi->common.mi;
michael@0 387 pbi->common.mi = tmp;
michael@0 388
michael@0 389 /* Propagate the segment_ids to the next frame */
michael@0 390 for (row = 0; row < pbi->common.mb_rows; ++row)
michael@0 391 {
michael@0 392 for (col = 0; col < pbi->common.mb_cols; ++col)
michael@0 393 {
michael@0 394 const int i = row*pbi->common.mode_info_stride + col;
michael@0 395 pbi->common.mi[i].mbmi.segment_id =
michael@0 396 pbi->common.prev_mi[i].mbmi.segment_id;
michael@0 397 }
michael@0 398 }
michael@0 399 }
michael@0 400 #endif
michael@0 401
michael@0 402 pbi->ready_for_new_data = 0;
michael@0 403 pbi->last_time_stamp = time_stamp;
michael@0 404
michael@0 405 decode_exit:
michael@0 406 #if HAVE_NEON
michael@0 407 #if CONFIG_RUNTIME_CPU_DETECT
michael@0 408 if (cm->cpu_caps & HAS_NEON)
michael@0 409 #endif
michael@0 410 {
michael@0 411 vp8_pop_neon(dx_store_reg);
michael@0 412 }
michael@0 413 #endif
michael@0 414
michael@0 415 pbi->common.error.setjmp = 0;
michael@0 416 return retcode;
michael@0 417 }
michael@0 418 int vp8dx_get_raw_frame(VP8D_COMP *pbi, YV12_BUFFER_CONFIG *sd, int64_t *time_stamp, int64_t *time_end_stamp, vp8_ppflags_t *flags)
michael@0 419 {
michael@0 420 int ret = -1;
michael@0 421
michael@0 422 if (pbi->ready_for_new_data == 1)
michael@0 423 return ret;
michael@0 424
michael@0 425 /* ie no raw frame to show!!! */
michael@0 426 if (pbi->common.show_frame == 0)
michael@0 427 return ret;
michael@0 428
michael@0 429 pbi->ready_for_new_data = 1;
michael@0 430 *time_stamp = pbi->last_time_stamp;
michael@0 431 *time_end_stamp = 0;
michael@0 432
michael@0 433 #if CONFIG_POSTPROC
michael@0 434 ret = vp8_post_proc_frame(&pbi->common, sd, flags);
michael@0 435 #else
michael@0 436
michael@0 437 if (pbi->common.frame_to_show)
michael@0 438 {
michael@0 439 *sd = *pbi->common.frame_to_show;
michael@0 440 sd->y_width = pbi->common.Width;
michael@0 441 sd->y_height = pbi->common.Height;
michael@0 442 sd->uv_height = pbi->common.Height / 2;
michael@0 443 ret = 0;
michael@0 444 }
michael@0 445 else
michael@0 446 {
michael@0 447 ret = -1;
michael@0 448 }
michael@0 449
michael@0 450 #endif /*!CONFIG_POSTPROC*/
michael@0 451 vp8_clear_system_state();
michael@0 452 return ret;
michael@0 453 }
michael@0 454
michael@0 455
michael@0 456 /* This function as written isn't decoder specific, but the encoder has
michael@0 457 * much faster ways of computing this, so it's ok for it to live in a
michael@0 458 * decode specific file.
michael@0 459 */
michael@0 460 int vp8dx_references_buffer( VP8_COMMON *oci, int ref_frame )
michael@0 461 {
michael@0 462 const MODE_INFO *mi = oci->mi;
michael@0 463 int mb_row, mb_col;
michael@0 464
michael@0 465 for (mb_row = 0; mb_row < oci->mb_rows; mb_row++)
michael@0 466 {
michael@0 467 for (mb_col = 0; mb_col < oci->mb_cols; mb_col++,mi++)
michael@0 468 {
michael@0 469 if( mi->mbmi.ref_frame == ref_frame)
michael@0 470 return 1;
michael@0 471 }
michael@0 472 mi++;
michael@0 473 }
michael@0 474 return 0;
michael@0 475
michael@0 476 }
michael@0 477
michael@0 478 int vp8_create_decoder_instances(struct frame_buffers *fb, VP8D_CONFIG *oxcf)
michael@0 479 {
michael@0 480 if(!fb->use_frame_threads)
michael@0 481 {
michael@0 482 /* decoder instance for single thread mode */
michael@0 483 fb->pbi[0] = create_decompressor(oxcf);
michael@0 484 if(!fb->pbi[0])
michael@0 485 return VPX_CODEC_ERROR;
michael@0 486
michael@0 487 #if CONFIG_MULTITHREAD
michael@0 488 /* enable row-based threading only when use_frame_threads
michael@0 489 * is disabled */
michael@0 490 fb->pbi[0]->max_threads = oxcf->max_threads;
michael@0 491 vp8_decoder_create_threads(fb->pbi[0]);
michael@0 492 #endif
michael@0 493 }
michael@0 494 else
michael@0 495 {
michael@0 496 /* TODO : create frame threads and decoder instances for each
michael@0 497 * thread here */
michael@0 498 }
michael@0 499
michael@0 500 return VPX_CODEC_OK;
michael@0 501 }
michael@0 502
michael@0 503 int vp8_remove_decoder_instances(struct frame_buffers *fb)
michael@0 504 {
michael@0 505 if(!fb->use_frame_threads)
michael@0 506 {
michael@0 507 VP8D_COMP *pbi = fb->pbi[0];
michael@0 508
michael@0 509 if (!pbi)
michael@0 510 return VPX_CODEC_ERROR;
michael@0 511 #if CONFIG_MULTITHREAD
michael@0 512 if (pbi->b_multithreaded_rd)
michael@0 513 vp8mt_de_alloc_temp_buffers(pbi, pbi->common.mb_rows);
michael@0 514 vp8_decoder_remove_threads(pbi);
michael@0 515 #endif
michael@0 516
michael@0 517 /* decoder instance for single thread mode */
michael@0 518 remove_decompressor(pbi);
michael@0 519 }
michael@0 520 else
michael@0 521 {
michael@0 522 /* TODO : remove frame threads and decoder instances for each
michael@0 523 * thread here */
michael@0 524 }
michael@0 525
michael@0 526 return VPX_CODEC_OK;
michael@0 527 }

mercurial