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