LCOV - code coverage report
Current view: top level - third_party/aom/av1/decoder - dthread.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 69 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 6 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 "./aom_config.h"
      13             : #include "aom_mem/aom_mem.h"
      14             : #include "av1/common/reconinter.h"
      15             : #include "av1/decoder/dthread.h"
      16             : #include "av1/decoder/decoder.h"
      17             : 
      18             : // #define DEBUG_THREAD
      19             : 
      20             : // TODO(hkuang): Clean up all the #ifdef in this file.
      21           0 : void av1_frameworker_lock_stats(AVxWorker *const worker) {
      22             : #if CONFIG_MULTITHREAD
      23           0 :   FrameWorkerData *const worker_data = worker->data1;
      24           0 :   pthread_mutex_lock(&worker_data->stats_mutex);
      25             : #else
      26             :   (void)worker;
      27             : #endif
      28           0 : }
      29             : 
      30           0 : void av1_frameworker_unlock_stats(AVxWorker *const worker) {
      31             : #if CONFIG_MULTITHREAD
      32           0 :   FrameWorkerData *const worker_data = worker->data1;
      33           0 :   pthread_mutex_unlock(&worker_data->stats_mutex);
      34             : #else
      35             :   (void)worker;
      36             : #endif
      37           0 : }
      38             : 
      39           0 : void av1_frameworker_signal_stats(AVxWorker *const worker) {
      40             : #if CONFIG_MULTITHREAD
      41           0 :   FrameWorkerData *const worker_data = worker->data1;
      42             : 
      43             : // TODO(hkuang): Fix the pthread_cond_broadcast in windows wrapper.
      44             : #if defined(_WIN32) && !HAVE_PTHREAD_H
      45             :   pthread_cond_signal(&worker_data->stats_cond);
      46             : #else
      47           0 :   pthread_cond_broadcast(&worker_data->stats_cond);
      48             : #endif
      49             : 
      50             : #else
      51             :   (void)worker;
      52             : #endif
      53           0 : }
      54             : 
      55             : // This macro prevents thread_sanitizer from reporting known concurrent writes.
      56             : #if defined(__has_feature)
      57             : #if __has_feature(thread_sanitizer)
      58             : #define BUILDING_WITH_TSAN
      59             : #endif
      60             : #endif
      61             : 
      62             : // TODO(hkuang): Remove worker parameter as it is only used in debug code.
      63           0 : void av1_frameworker_wait(AVxWorker *const worker, RefCntBuffer *const ref_buf,
      64             :                           int row) {
      65             : #if CONFIG_MULTITHREAD
      66           0 :   if (!ref_buf) return;
      67             : 
      68             : #ifndef BUILDING_WITH_TSAN
      69             :   // The following line of code will get harmless tsan error but it is the key
      70             :   // to get best performance.
      71           0 :   if (ref_buf->row >= row && ref_buf->buf.corrupted != 1) return;
      72             : #endif
      73             : 
      74             :   {
      75             :     // Find the worker thread that owns the reference frame. If the reference
      76             :     // frame has been fully decoded, it may not have owner.
      77           0 :     AVxWorker *const ref_worker = ref_buf->frame_worker_owner;
      78           0 :     FrameWorkerData *const ref_worker_data =
      79             :         (FrameWorkerData *)ref_worker->data1;
      80           0 :     const AV1Decoder *const pbi = ref_worker_data->pbi;
      81             : 
      82             : #ifdef DEBUG_THREAD
      83             :     {
      84             :       FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1;
      85             :       printf("%d %p worker is waiting for %d %p worker (%d)  ref %d \r\n",
      86             :              worker_data->worker_id, worker, ref_worker_data->worker_id,
      87             :              ref_buf->frame_worker_owner, row, ref_buf->row);
      88             :     }
      89             : #endif
      90             : 
      91           0 :     av1_frameworker_lock_stats(ref_worker);
      92           0 :     while (ref_buf->row < row && pbi->cur_buf == ref_buf &&
      93           0 :            ref_buf->buf.corrupted != 1) {
      94           0 :       pthread_cond_wait(&ref_worker_data->stats_cond,
      95             :                         &ref_worker_data->stats_mutex);
      96             :     }
      97             : 
      98           0 :     if (ref_buf->buf.corrupted == 1) {
      99           0 :       FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1;
     100           0 :       av1_frameworker_unlock_stats(ref_worker);
     101           0 :       aom_internal_error(&worker_data->pbi->common.error,
     102             :                          AOM_CODEC_CORRUPT_FRAME,
     103             :                          "Worker %p failed to decode frame", worker);
     104             :     }
     105           0 :     av1_frameworker_unlock_stats(ref_worker);
     106             :   }
     107             : #else
     108             :   (void)worker;
     109             :   (void)ref_buf;
     110             :   (void)row;
     111             :   (void)ref_buf;
     112             : #endif  // CONFIG_MULTITHREAD
     113             : }
     114             : 
     115           0 : void av1_frameworker_broadcast(RefCntBuffer *const buf, int row) {
     116             : #if CONFIG_MULTITHREAD
     117           0 :   AVxWorker *worker = buf->frame_worker_owner;
     118             : 
     119             : #ifdef DEBUG_THREAD
     120             :   {
     121             :     FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1;
     122             :     printf("%d %p worker decode to (%d) \r\n", worker_data->worker_id,
     123             :            buf->frame_worker_owner, row);
     124             :   }
     125             : #endif
     126             : 
     127           0 :   av1_frameworker_lock_stats(worker);
     128           0 :   buf->row = row;
     129           0 :   av1_frameworker_signal_stats(worker);
     130           0 :   av1_frameworker_unlock_stats(worker);
     131             : #else
     132             :   (void)buf;
     133             :   (void)row;
     134             : #endif  // CONFIG_MULTITHREAD
     135           0 : }
     136             : 
     137           0 : void av1_frameworker_copy_context(AVxWorker *const dst_worker,
     138             :                                   AVxWorker *const src_worker) {
     139             : #if CONFIG_MULTITHREAD
     140           0 :   FrameWorkerData *const src_worker_data = (FrameWorkerData *)src_worker->data1;
     141           0 :   FrameWorkerData *const dst_worker_data = (FrameWorkerData *)dst_worker->data1;
     142           0 :   AV1_COMMON *const src_cm = &src_worker_data->pbi->common;
     143           0 :   AV1_COMMON *const dst_cm = &dst_worker_data->pbi->common;
     144             :   int i;
     145             : 
     146             :   // Wait until source frame's context is ready.
     147           0 :   av1_frameworker_lock_stats(src_worker);
     148           0 :   while (!src_worker_data->frame_context_ready) {
     149           0 :     pthread_cond_wait(&src_worker_data->stats_cond,
     150             :                       &src_worker_data->stats_mutex);
     151             :   }
     152             : 
     153           0 :   dst_cm->last_frame_seg_map = src_cm->seg.enabled
     154             :                                    ? src_cm->current_frame_seg_map
     155           0 :                                    : src_cm->last_frame_seg_map;
     156           0 :   dst_worker_data->pbi->need_resync = src_worker_data->pbi->need_resync;
     157           0 :   av1_frameworker_unlock_stats(src_worker);
     158             : 
     159           0 :   dst_cm->bit_depth = src_cm->bit_depth;
     160             : #if CONFIG_HIGHBITDEPTH
     161           0 :   dst_cm->use_highbitdepth = src_cm->use_highbitdepth;
     162             : #endif
     163             : #if CONFIG_EXT_REFS
     164             : // TODO(zoeliu): To handle parallel decoding
     165             : #endif  // CONFIG_EXT_REFS
     166           0 :   dst_cm->prev_frame =
     167           0 :       src_cm->show_existing_frame ? src_cm->prev_frame : src_cm->cur_frame;
     168           0 :   dst_cm->last_width =
     169           0 :       !src_cm->show_existing_frame ? src_cm->width : src_cm->last_width;
     170           0 :   dst_cm->last_height =
     171           0 :       !src_cm->show_existing_frame ? src_cm->height : src_cm->last_height;
     172           0 :   dst_cm->subsampling_x = src_cm->subsampling_x;
     173           0 :   dst_cm->subsampling_y = src_cm->subsampling_y;
     174           0 :   dst_cm->frame_type = src_cm->frame_type;
     175           0 :   dst_cm->last_show_frame = !src_cm->show_existing_frame
     176             :                                 ? src_cm->show_frame
     177           0 :                                 : src_cm->last_show_frame;
     178           0 :   for (i = 0; i < REF_FRAMES; ++i)
     179           0 :     dst_cm->ref_frame_map[i] = src_cm->next_ref_frame_map[i];
     180             : 
     181           0 :   memcpy(dst_cm->lf_info.lfthr, src_cm->lf_info.lfthr,
     182             :          (MAX_LOOP_FILTER + 1) * sizeof(loop_filter_thresh));
     183           0 :   dst_cm->lf.last_sharpness_level = src_cm->lf.sharpness_level;
     184           0 :   dst_cm->lf.filter_level = src_cm->lf.filter_level;
     185           0 :   memcpy(dst_cm->lf.ref_deltas, src_cm->lf.ref_deltas, TOTAL_REFS_PER_FRAME);
     186           0 :   memcpy(dst_cm->lf.mode_deltas, src_cm->lf.mode_deltas, MAX_MODE_LF_DELTAS);
     187           0 :   dst_cm->seg = src_cm->seg;
     188           0 :   memcpy(dst_cm->frame_contexts, src_cm->frame_contexts,
     189             :          FRAME_CONTEXTS * sizeof(dst_cm->frame_contexts[0]));
     190             : #else
     191             :   (void)dst_worker;
     192             :   (void)src_worker;
     193             : #endif  // CONFIG_MULTITHREAD
     194           0 : }

Generated by: LCOV version 1.13