LCOV - code coverage report
Current view: top level - third_party/aom/av1/decoder - decoder.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 269 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) 2016, Alliance for Open Media. All rights reserved
       3             :  *
       4             :  * This source code is subject to the terms of the BSD 2 Clause License and
       5             :  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
       6             :  * was not distributed with this source code in the LICENSE file, you can
       7             :  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
       8             :  * Media Patent License 1.0 was not distributed with this source code in the
       9             :  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
      10             :  */
      11             : 
      12             : #include <assert.h>
      13             : #include <limits.h>
      14             : #include <stdio.h>
      15             : 
      16             : #include "./av1_rtcd.h"
      17             : #include "./aom_dsp_rtcd.h"
      18             : #include "./aom_scale_rtcd.h"
      19             : 
      20             : #include "aom_mem/aom_mem.h"
      21             : #include "aom_ports/system_state.h"
      22             : #include "aom_ports/aom_once.h"
      23             : #include "aom_ports/aom_timer.h"
      24             : #include "aom_scale/aom_scale.h"
      25             : #include "aom_util/aom_thread.h"
      26             : 
      27             : #include "av1/common/alloccommon.h"
      28             : #include "av1/common/av1_loopfilter.h"
      29             : #include "av1/common/onyxc_int.h"
      30             : #include "av1/common/quant_common.h"
      31             : #include "av1/common/reconinter.h"
      32             : #include "av1/common/reconintra.h"
      33             : 
      34             : #include "av1/decoder/decodeframe.h"
      35             : #include "av1/decoder/decoder.h"
      36             : 
      37             : #if !CONFIG_PVQ
      38             : #include "av1/decoder/detokenize.h"
      39             : #endif
      40             : 
      41           0 : static void initialize_dec(void) {
      42             :   static volatile int init_done = 0;
      43             : 
      44           0 :   if (!init_done) {
      45           0 :     av1_rtcd();
      46           0 :     aom_dsp_rtcd();
      47           0 :     aom_scale_rtcd();
      48           0 :     av1_init_intra_predictors();
      49             : #if CONFIG_EXT_INTER
      50           0 :     av1_init_wedge_masks();
      51             : #endif  // CONFIG_EXT_INTER
      52           0 :     init_done = 1;
      53           0 :     av1_indices_from_tree(av1_intra_mode_ind, av1_intra_mode_inv,
      54             :                           av1_intra_mode_tree);
      55           0 :     av1_indices_from_tree(av1_switchable_interp_ind, av1_switchable_interp_inv,
      56             :                           av1_switchable_interp_tree);
      57             : #if CONFIG_EXT_TX
      58             :     int s;
      59           0 :     for (s = 1; s < EXT_TX_SETS_INTRA; ++s)
      60           0 :       av1_indices_from_tree(av1_ext_tx_intra_ind[s], av1_ext_tx_intra_inv[s],
      61           0 :                             av1_ext_tx_intra_tree[s]);
      62           0 :     for (s = 1; s < EXT_TX_SETS_INTER; ++s)
      63           0 :       av1_indices_from_tree(av1_ext_tx_inter_ind[s], av1_ext_tx_inter_inv[s],
      64           0 :                             av1_ext_tx_inter_tree[s]);
      65             : #else
      66             :     av1_indices_from_tree(av1_ext_tx_ind, av1_ext_tx_inv, av1_ext_tx_tree);
      67             : #endif
      68           0 :     av1_indices_from_tree(av1_inter_mode_ind, av1_inter_mode_inv,
      69             :                           av1_inter_mode_tree);
      70             :   }
      71           0 : }
      72             : 
      73           0 : static void av1_dec_setup_mi(AV1_COMMON *cm) {
      74           0 :   cm->mi = cm->mip + cm->mi_stride + 1;
      75           0 :   cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1;
      76           0 :   memset(cm->mi_grid_base, 0,
      77           0 :          cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mi_grid_base));
      78           0 : }
      79             : 
      80           0 : static int av1_dec_alloc_mi(AV1_COMMON *cm, int mi_size) {
      81           0 :   cm->mip = aom_calloc(mi_size, sizeof(*cm->mip));
      82           0 :   if (!cm->mip) return 1;
      83           0 :   cm->mi_alloc_size = mi_size;
      84           0 :   cm->mi_grid_base = (MODE_INFO **)aom_calloc(mi_size, sizeof(MODE_INFO *));
      85           0 :   if (!cm->mi_grid_base) return 1;
      86           0 :   return 0;
      87             : }
      88             : 
      89           0 : static void av1_dec_free_mi(AV1_COMMON *cm) {
      90           0 :   aom_free(cm->mip);
      91           0 :   cm->mip = NULL;
      92           0 :   aom_free(cm->mi_grid_base);
      93           0 :   cm->mi_grid_base = NULL;
      94           0 : }
      95             : 
      96           0 : AV1Decoder *av1_decoder_create(BufferPool *const pool) {
      97           0 :   AV1Decoder *volatile const pbi = aom_memalign(32, sizeof(*pbi));
      98           0 :   AV1_COMMON *volatile const cm = pbi ? &pbi->common : NULL;
      99             : 
     100           0 :   if (!cm) return NULL;
     101             : 
     102           0 :   av1_zero(*pbi);
     103             : 
     104           0 :   if (setjmp(cm->error.jmp)) {
     105           0 :     cm->error.setjmp = 0;
     106           0 :     av1_decoder_remove(pbi);
     107           0 :     return NULL;
     108             :   }
     109             : 
     110           0 :   cm->error.setjmp = 1;
     111             : 
     112           0 :   CHECK_MEM_ERROR(cm, cm->fc,
     113             :                   (FRAME_CONTEXT *)aom_memalign(32, sizeof(*cm->fc)));
     114           0 :   CHECK_MEM_ERROR(cm, cm->frame_contexts,
     115             :                   (FRAME_CONTEXT *)aom_memalign(
     116             :                       32, FRAME_CONTEXTS * sizeof(*cm->frame_contexts)));
     117           0 :   memset(cm->fc, 0, sizeof(*cm->fc));
     118           0 :   memset(cm->frame_contexts, 0, FRAME_CONTEXTS * sizeof(*cm->frame_contexts));
     119             : 
     120           0 :   pbi->need_resync = 1;
     121           0 :   once(initialize_dec);
     122             : 
     123             :   // Initialize the references to not point to any frame buffers.
     124           0 :   memset(&cm->ref_frame_map, -1, sizeof(cm->ref_frame_map));
     125           0 :   memset(&cm->next_ref_frame_map, -1, sizeof(cm->next_ref_frame_map));
     126             : 
     127           0 :   cm->current_video_frame = 0;
     128           0 :   pbi->ready_for_new_data = 1;
     129           0 :   pbi->common.buffer_pool = pool;
     130             : 
     131           0 :   cm->bit_depth = AOM_BITS_8;
     132           0 :   cm->dequant_bit_depth = AOM_BITS_8;
     133             : 
     134           0 :   cm->alloc_mi = av1_dec_alloc_mi;
     135           0 :   cm->free_mi = av1_dec_free_mi;
     136           0 :   cm->setup_mi = av1_dec_setup_mi;
     137             : 
     138           0 :   av1_loop_filter_init(cm);
     139             : 
     140             : #if CONFIG_AOM_QM
     141             :   aom_qm_init(cm);
     142             : #endif
     143             : #if CONFIG_LOOP_RESTORATION
     144             :   av1_loop_restoration_precal();
     145             : #endif  // CONFIG_LOOP_RESTORATION
     146             : #if CONFIG_ACCOUNTING
     147             :   pbi->acct_enabled = 1;
     148             :   aom_accounting_init(&pbi->accounting);
     149             : #endif
     150             : 
     151           0 :   cm->error.setjmp = 0;
     152             : 
     153           0 :   aom_get_worker_interface()->init(&pbi->lf_worker);
     154             : 
     155           0 :   return pbi;
     156             : }
     157             : 
     158           0 : void av1_decoder_remove(AV1Decoder *pbi) {
     159             :   int i;
     160             : 
     161           0 :   if (!pbi) return;
     162             : 
     163           0 :   aom_get_worker_interface()->end(&pbi->lf_worker);
     164           0 :   aom_free(pbi->lf_worker.data1);
     165           0 :   aom_free(pbi->tile_data);
     166           0 :   for (i = 0; i < pbi->num_tile_workers; ++i) {
     167           0 :     AVxWorker *const worker = &pbi->tile_workers[i];
     168           0 :     aom_get_worker_interface()->end(worker);
     169             :   }
     170           0 :   aom_free(pbi->tile_worker_data);
     171           0 :   aom_free(pbi->tile_worker_info);
     172           0 :   aom_free(pbi->tile_workers);
     173             : 
     174           0 :   if (pbi->num_tile_workers > 0) {
     175           0 :     av1_loop_filter_dealloc(&pbi->lf_row_sync);
     176             :   }
     177             : 
     178             : #if CONFIG_ACCOUNTING
     179             :   aom_accounting_clear(&pbi->accounting);
     180             : #endif
     181             : 
     182           0 :   aom_free(pbi);
     183             : }
     184             : 
     185           0 : static int equal_dimensions(const YV12_BUFFER_CONFIG *a,
     186             :                             const YV12_BUFFER_CONFIG *b) {
     187           0 :   return a->y_height == b->y_height && a->y_width == b->y_width &&
     188           0 :          a->uv_height == b->uv_height && a->uv_width == b->uv_width;
     189             : }
     190             : 
     191           0 : aom_codec_err_t av1_copy_reference_dec(AV1Decoder *pbi,
     192             :                                        AOM_REFFRAME ref_frame_flag,
     193             :                                        YV12_BUFFER_CONFIG *sd) {
     194           0 :   AV1_COMMON *cm = &pbi->common;
     195             : 
     196             :   /* TODO(jkoleszar): The decoder doesn't have any real knowledge of what the
     197             :    * encoder is using the frame buffers for. This is just a stub to keep the
     198             :    * aomenc --test-decode functionality working, and will be replaced in a
     199             :    * later commit that adds AV1-specific controls for this functionality.
     200             :    */
     201           0 :   if (ref_frame_flag == AOM_LAST_FLAG) {
     202           0 :     const YV12_BUFFER_CONFIG *const cfg = get_ref_frame(cm, 0);
     203           0 :     if (cfg == NULL) {
     204           0 :       aom_internal_error(&cm->error, AOM_CODEC_ERROR,
     205             :                          "No 'last' reference frame");
     206           0 :       return AOM_CODEC_ERROR;
     207             :     }
     208           0 :     if (!equal_dimensions(cfg, sd))
     209           0 :       aom_internal_error(&cm->error, AOM_CODEC_ERROR,
     210             :                          "Incorrect buffer dimensions");
     211             :     else
     212           0 :       aom_yv12_copy_frame(cfg, sd);
     213             :   } else {
     214           0 :     aom_internal_error(&cm->error, AOM_CODEC_ERROR, "Invalid reference frame");
     215             :   }
     216             : 
     217           0 :   return cm->error.error_code;
     218             : }
     219             : 
     220           0 : aom_codec_err_t av1_set_reference_dec(AV1_COMMON *cm,
     221             :                                       AOM_REFFRAME ref_frame_flag,
     222             :                                       YV12_BUFFER_CONFIG *sd) {
     223             :   int idx;
     224           0 :   YV12_BUFFER_CONFIG *ref_buf = NULL;
     225             : 
     226             :   // TODO(jkoleszar): The decoder doesn't have any real knowledge of what the
     227             :   // encoder is using the frame buffers for. This is just a stub to keep the
     228             :   // aomenc --test-decode functionality working, and will be replaced in a
     229             :   // later commit that adds AV1-specific controls for this functionality.
     230             : 
     231             :   // (Yunqing) The set_reference control depends on the following setting in
     232             :   // encoder.
     233             :   //   cpi->lst_fb_idx = 0;
     234             :   // #if CONFIG_EXT_REFS
     235             :   //   cpi->lst2_fb_idx = 1;
     236             :   //   cpi->lst3_fb_idx = 2;
     237             :   //   cpi->gld_fb_idx = 3;
     238             :   //   cpi->bwd_fb_idx = 4;
     239             :   //   cpi->alt_fb_idx = 5;
     240             :   // #else  // CONFIG_EXT_REFS
     241             :   //   cpi->gld_fb_idx = 1;
     242             :   //   cpi->alt_fb_idx = 2;
     243             :   // #endif  // CONFIG_EXT_REFS
     244             : 
     245             :   // TODO(zoeliu): To revisit following code and reconsider what assumption we
     246             :   // may take on the reference frame buffer virtual indexes
     247           0 :   if (ref_frame_flag == AOM_LAST_FLAG) {
     248           0 :     idx = cm->ref_frame_map[0];
     249             : #if CONFIG_EXT_REFS
     250           0 :   } else if (ref_frame_flag == AOM_LAST2_FLAG) {
     251           0 :     idx = cm->ref_frame_map[1];
     252           0 :   } else if (ref_frame_flag == AOM_LAST3_FLAG) {
     253           0 :     idx = cm->ref_frame_map[2];
     254           0 :   } else if (ref_frame_flag == AOM_GOLD_FLAG) {
     255           0 :     idx = cm->ref_frame_map[3];
     256           0 :   } else if (ref_frame_flag == AOM_BWD_FLAG) {
     257           0 :     idx = cm->ref_frame_map[4];
     258           0 :   } else if (ref_frame_flag == AOM_ALT_FLAG) {
     259           0 :     idx = cm->ref_frame_map[5];
     260             : #else
     261             :   } else if (ref_frame_flag == AOM_GOLD_FLAG) {
     262             :     idx = cm->ref_frame_map[1];
     263             :   } else if (ref_frame_flag == AOM_ALT_FLAG) {
     264             :     idx = cm->ref_frame_map[2];
     265             : #endif  // CONFIG_EXT_REFS
     266             :   } else {
     267           0 :     aom_internal_error(&cm->error, AOM_CODEC_ERROR, "Invalid reference frame");
     268           0 :     return cm->error.error_code;
     269             :   }
     270             : 
     271           0 :   if (idx < 0 || idx >= FRAME_BUFFERS) {
     272           0 :     aom_internal_error(&cm->error, AOM_CODEC_ERROR,
     273             :                        "Invalid reference frame map");
     274           0 :     return cm->error.error_code;
     275             :   }
     276             : 
     277             :   // Get the destination reference buffer.
     278           0 :   ref_buf = &cm->buffer_pool->frame_bufs[idx].buf;
     279             : 
     280           0 :   if (!equal_dimensions(ref_buf, sd)) {
     281           0 :     aom_internal_error(&cm->error, AOM_CODEC_ERROR,
     282             :                        "Incorrect buffer dimensions");
     283             :   } else {
     284             :     // Overwrite the reference frame buffer.
     285           0 :     aom_yv12_copy_frame(sd, ref_buf);
     286             :   }
     287             : 
     288           0 :   return cm->error.error_code;
     289             : }
     290             : 
     291             : /* If any buffer updating is signaled it should be done here. */
     292           0 : static void swap_frame_buffers(AV1Decoder *pbi) {
     293           0 :   int ref_index = 0, mask;
     294           0 :   AV1_COMMON *const cm = &pbi->common;
     295           0 :   BufferPool *const pool = cm->buffer_pool;
     296           0 :   RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
     297             : 
     298           0 :   lock_buffer_pool(pool);
     299           0 :   for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) {
     300           0 :     const int old_idx = cm->ref_frame_map[ref_index];
     301             :     // Current thread releases the holding of reference frame.
     302           0 :     decrease_ref_count(old_idx, frame_bufs, pool);
     303             : 
     304             :     // Release the reference frame holding in the reference map for the decoding
     305             :     // of the next frame.
     306           0 :     if (mask & 1) decrease_ref_count(old_idx, frame_bufs, pool);
     307           0 :     cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index];
     308           0 :     ++ref_index;
     309             :   }
     310             : 
     311             :   // Current thread releases the holding of reference frame.
     312           0 :   for (; ref_index < REF_FRAMES && !cm->show_existing_frame; ++ref_index) {
     313           0 :     const int old_idx = cm->ref_frame_map[ref_index];
     314           0 :     decrease_ref_count(old_idx, frame_bufs, pool);
     315           0 :     cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index];
     316             :   }
     317             : 
     318           0 :   unlock_buffer_pool(pool);
     319           0 :   pbi->hold_ref_buf = 0;
     320           0 :   cm->frame_to_show = get_frame_new_buffer(cm);
     321             : 
     322             :   // TODO(zoeliu): To fix the ref frame buffer update for the scenario of
     323             :   //               cm->frame_parellel_decode == 1
     324           0 :   if (!cm->frame_parallel_decode || !cm->show_frame) {
     325           0 :     lock_buffer_pool(pool);
     326           0 :     --frame_bufs[cm->new_fb_idx].ref_count;
     327           0 :     unlock_buffer_pool(pool);
     328             :   }
     329             : 
     330             :   // Invalidate these references until the next frame starts.
     331           0 :   for (ref_index = 0; ref_index < INTER_REFS_PER_FRAME; ref_index++) {
     332           0 :     cm->frame_refs[ref_index].idx = INVALID_IDX;
     333           0 :     cm->frame_refs[ref_index].buf = NULL;
     334             :   }
     335           0 : }
     336             : 
     337           0 : int av1_receive_compressed_data(AV1Decoder *pbi, size_t size,
     338             :                                 const uint8_t **psource) {
     339           0 :   AV1_COMMON *volatile const cm = &pbi->common;
     340           0 :   BufferPool *volatile const pool = cm->buffer_pool;
     341           0 :   RefCntBuffer *volatile const frame_bufs = cm->buffer_pool->frame_bufs;
     342           0 :   const uint8_t *source = *psource;
     343           0 :   int retcode = 0;
     344           0 :   cm->error.error_code = AOM_CODEC_OK;
     345             : 
     346           0 :   if (size == 0) {
     347             :     // This is used to signal that we are missing frames.
     348             :     // We do not know if the missing frame(s) was supposed to update
     349             :     // any of the reference buffers, but we act conservative and
     350             :     // mark only the last buffer as corrupted.
     351             :     //
     352             :     // TODO(jkoleszar): Error concealment is undefined and non-normative
     353             :     // at this point, but if it becomes so, [0] may not always be the correct
     354             :     // thing to do here.
     355           0 :     if (cm->frame_refs[0].idx > 0) {
     356           0 :       assert(cm->frame_refs[0].buf != NULL);
     357           0 :       cm->frame_refs[0].buf->corrupted = 1;
     358             :     }
     359             :   }
     360             : 
     361           0 :   pbi->ready_for_new_data = 0;
     362             : 
     363             :   // Find a free buffer for the new frame, releasing the reference previously
     364             :   // held.
     365             : 
     366             :   // Check if the previous frame was a frame without any references to it.
     367             :   // Release frame buffer if not decoding in frame parallel mode.
     368           0 :   if (!cm->frame_parallel_decode && cm->new_fb_idx >= 0 &&
     369           0 :       frame_bufs[cm->new_fb_idx].ref_count == 0)
     370           0 :     pool->release_fb_cb(pool->cb_priv,
     371           0 :                         &frame_bufs[cm->new_fb_idx].raw_frame_buffer);
     372             : 
     373             :   // Find a free frame buffer. Return error if can not find any.
     374           0 :   cm->new_fb_idx = get_free_fb(cm);
     375           0 :   if (cm->new_fb_idx == INVALID_IDX) return AOM_CODEC_MEM_ERROR;
     376             : 
     377             :   // Assign a MV array to the frame buffer.
     378           0 :   cm->cur_frame = &pool->frame_bufs[cm->new_fb_idx];
     379             : 
     380           0 :   pbi->hold_ref_buf = 0;
     381           0 :   if (cm->frame_parallel_decode) {
     382           0 :     AVxWorker *const worker = pbi->frame_worker_owner;
     383           0 :     av1_frameworker_lock_stats(worker);
     384           0 :     frame_bufs[cm->new_fb_idx].frame_worker_owner = worker;
     385             :     // Reset decoding progress.
     386           0 :     pbi->cur_buf = &frame_bufs[cm->new_fb_idx];
     387           0 :     pbi->cur_buf->row = -1;
     388           0 :     pbi->cur_buf->col = -1;
     389           0 :     av1_frameworker_unlock_stats(worker);
     390             :   } else {
     391           0 :     pbi->cur_buf = &frame_bufs[cm->new_fb_idx];
     392             :   }
     393             : 
     394           0 :   if (setjmp(cm->error.jmp)) {
     395           0 :     const AVxWorkerInterface *const winterface = aom_get_worker_interface();
     396             :     int i;
     397             : 
     398           0 :     cm->error.setjmp = 0;
     399           0 :     pbi->ready_for_new_data = 1;
     400             : 
     401             :     // Synchronize all threads immediately as a subsequent decode call may
     402             :     // cause a resize invalidating some allocations.
     403           0 :     winterface->sync(&pbi->lf_worker);
     404           0 :     for (i = 0; i < pbi->num_tile_workers; ++i) {
     405           0 :       winterface->sync(&pbi->tile_workers[i]);
     406             :     }
     407             : 
     408           0 :     lock_buffer_pool(pool);
     409             :     // Release all the reference buffers if worker thread is holding them.
     410           0 :     if (pbi->hold_ref_buf == 1) {
     411           0 :       int ref_index = 0, mask;
     412           0 :       for (mask = pbi->refresh_frame_flags; mask; mask >>= 1) {
     413           0 :         const int old_idx = cm->ref_frame_map[ref_index];
     414             :         // Current thread releases the holding of reference frame.
     415           0 :         decrease_ref_count(old_idx, frame_bufs, pool);
     416             : 
     417             :         // Release the reference frame holding in the reference map for the
     418             :         // decoding of the next frame.
     419           0 :         if (mask & 1) decrease_ref_count(old_idx, frame_bufs, pool);
     420           0 :         ++ref_index;
     421             :       }
     422             : 
     423             :       // Current thread releases the holding of reference frame.
     424           0 :       for (; ref_index < REF_FRAMES && !cm->show_existing_frame; ++ref_index) {
     425           0 :         const int old_idx = cm->ref_frame_map[ref_index];
     426           0 :         decrease_ref_count(old_idx, frame_bufs, pool);
     427             :       }
     428           0 :       pbi->hold_ref_buf = 0;
     429             :     }
     430             :     // Release current frame.
     431           0 :     decrease_ref_count(cm->new_fb_idx, frame_bufs, pool);
     432           0 :     unlock_buffer_pool(pool);
     433             : 
     434           0 :     aom_clear_system_state();
     435           0 :     return -1;
     436             :   }
     437             : 
     438           0 :   cm->error.setjmp = 1;
     439           0 :   av1_decode_frame(pbi, source, source + size, psource);
     440             : 
     441           0 :   swap_frame_buffers(pbi);
     442             : 
     443             : #if CONFIG_EXT_TILE
     444             :   // For now, we only extend the frame borders when the whole frame is decoded.
     445             :   // Later, if needed, extend the border for the decoded tile on the frame
     446             :   // border.
     447             :   if (pbi->dec_tile_row == -1 && pbi->dec_tile_col == -1)
     448             : #endif  // CONFIG_EXT_TILE
     449           0 :     aom_extend_frame_inner_borders(cm->frame_to_show);
     450             : 
     451           0 :   aom_clear_system_state();
     452             : 
     453           0 :   if (!cm->show_existing_frame) {
     454           0 :     cm->last_show_frame = cm->show_frame;
     455             : 
     456             : #if CONFIG_EXT_REFS
     457             :     // NOTE: It is not supposed to ref to any frame not used as reference
     458           0 :     if (cm->is_reference_frame)
     459             : #endif  // CONFIG_EXT_REFS
     460           0 :       cm->prev_frame = cm->cur_frame;
     461             : 
     462           0 :     if (cm->seg.enabled && !cm->frame_parallel_decode)
     463           0 :       av1_swap_current_and_last_seg_map(cm);
     464             :   }
     465             : 
     466             :   // Update progress in frame parallel decode.
     467           0 :   if (cm->frame_parallel_decode) {
     468             :     // Need to lock the mutex here as another thread may
     469             :     // be accessing this buffer.
     470           0 :     AVxWorker *const worker = pbi->frame_worker_owner;
     471           0 :     FrameWorkerData *const frame_worker_data = worker->data1;
     472           0 :     av1_frameworker_lock_stats(worker);
     473             : 
     474           0 :     if (cm->show_frame) {
     475           0 :       cm->current_video_frame++;
     476             :     }
     477           0 :     frame_worker_data->frame_decoded = 1;
     478           0 :     frame_worker_data->frame_context_ready = 1;
     479           0 :     av1_frameworker_signal_stats(worker);
     480           0 :     av1_frameworker_unlock_stats(worker);
     481             :   } else {
     482           0 :     cm->last_width = cm->width;
     483           0 :     cm->last_height = cm->height;
     484           0 :     if (cm->show_frame) {
     485           0 :       cm->current_video_frame++;
     486             :     }
     487             :   }
     488             : 
     489           0 :   cm->error.setjmp = 0;
     490           0 :   return retcode;
     491             : }
     492             : 
     493           0 : int av1_get_raw_frame(AV1Decoder *pbi, YV12_BUFFER_CONFIG *sd) {
     494           0 :   AV1_COMMON *const cm = &pbi->common;
     495           0 :   int ret = -1;
     496           0 :   if (pbi->ready_for_new_data == 1) return ret;
     497             : 
     498           0 :   pbi->ready_for_new_data = 1;
     499             : 
     500             :   /* no raw frame to show!!! */
     501           0 :   if (!cm->show_frame) return ret;
     502             : 
     503           0 :   pbi->ready_for_new_data = 1;
     504           0 :   *sd = *cm->frame_to_show;
     505           0 :   ret = 0;
     506           0 :   aom_clear_system_state();
     507           0 :   return ret;
     508             : }
     509             : 
     510           0 : int av1_get_frame_to_show(AV1Decoder *pbi, YV12_BUFFER_CONFIG *frame) {
     511           0 :   AV1_COMMON *const cm = &pbi->common;
     512             : 
     513           0 :   if (!cm->show_frame || !cm->frame_to_show) return -1;
     514             : 
     515           0 :   *frame = *cm->frame_to_show;
     516           0 :   return 0;
     517             : }
     518             : 
     519           0 : aom_codec_err_t av1_parse_superframe_index(const uint8_t *data, size_t data_sz,
     520             :                                            uint32_t sizes[8], int *count,
     521             :                                            aom_decrypt_cb decrypt_cb,
     522             :                                            void *decrypt_state) {
     523             :   // A chunk ending with a byte matching 0xc0 is an invalid chunk unless
     524             :   // it is a super frame index. If the last byte of real video compression
     525             :   // data is 0xc0 the encoder must add a 0 byte. If we have the marker but
     526             :   // not the associated matching marker byte at the front of the index we have
     527             :   // an invalid bitstream and need to return an error.
     528             : 
     529             :   uint8_t marker;
     530           0 :   size_t frame_sz_sum = 0;
     531             : 
     532           0 :   assert(data_sz);
     533           0 :   marker = read_marker(decrypt_cb, decrypt_state, data + data_sz - 1);
     534           0 :   *count = 0;
     535             : 
     536           0 :   if ((marker & 0xe0) == 0xc0) {
     537           0 :     const uint32_t frames = (marker & 0x7) + 1;
     538           0 :     const uint32_t mag = ((marker >> 3) & 0x3) + 1;
     539           0 :     const size_t index_sz = 2 + mag * (frames - 1);
     540             : 
     541             :     // This chunk is marked as having a superframe index but doesn't have
     542             :     // enough data for it, thus it's an invalid superframe index.
     543           0 :     if (data_sz < index_sz) return AOM_CODEC_CORRUPT_FRAME;
     544             : 
     545             :     {
     546           0 :       const uint8_t marker2 =
     547           0 :           read_marker(decrypt_cb, decrypt_state, data + data_sz - index_sz);
     548             : 
     549             :       // This chunk is marked as having a superframe index but doesn't have
     550             :       // the matching marker byte at the front of the index therefore it's an
     551             :       // invalid chunk.
     552           0 :       if (marker != marker2) return AOM_CODEC_CORRUPT_FRAME;
     553             :     }
     554             : 
     555             :     {
     556             :       // Found a valid superframe index.
     557             :       uint32_t i, j;
     558           0 :       const uint8_t *x = &data[data_sz - index_sz + 1];
     559             : 
     560             :       // Frames has a maximum of 8 and mag has a maximum of 4.
     561             :       uint8_t clear_buffer[28];
     562           0 :       assert(sizeof(clear_buffer) >= (frames - 1) * mag);
     563           0 :       if (decrypt_cb) {
     564           0 :         decrypt_cb(decrypt_state, x, clear_buffer, (frames - 1) * mag);
     565           0 :         x = clear_buffer;
     566             :       }
     567             : 
     568           0 :       for (i = 0; i < frames - 1; ++i) {
     569           0 :         uint32_t this_sz = 0;
     570             : 
     571           0 :         for (j = 0; j < mag; ++j) this_sz |= (*x++) << (j * 8);
     572           0 :         this_sz += 1;
     573           0 :         sizes[i] = this_sz;
     574           0 :         frame_sz_sum += this_sz;
     575             :       }
     576           0 :       sizes[i] = (uint32_t)(data_sz - index_sz - frame_sz_sum);
     577           0 :       *count = frames;
     578             :     }
     579             :   }
     580           0 :   return AOM_CODEC_OK;
     581             : }

Generated by: LCOV version 1.13