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

Generated by: LCOV version 1.13