LCOV - code coverage report
Current view: top level - media/libvpx/libvpx/vp8/decoder - onyxd_if.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 193 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 14 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13