LCOV - code coverage report
Current view: top level - media/libvpx/libvpx/vp8 - vp8_dx_iface.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 272 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 20 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 <assert.h>
      12             : #include <stdlib.h>
      13             : #include <string.h>
      14             : #include "./vp8_rtcd.h"
      15             : #include "./vpx_dsp_rtcd.h"
      16             : #include "./vpx_scale_rtcd.h"
      17             : #include "vpx/vpx_decoder.h"
      18             : #include "vpx/vp8dx.h"
      19             : #include "vpx/internal/vpx_codec_internal.h"
      20             : #include "vpx_version.h"
      21             : #include "common/alloccommon.h"
      22             : #include "common/common.h"
      23             : #include "common/onyxd.h"
      24             : #include "decoder/onyxd_int.h"
      25             : #include "vpx_dsp/vpx_dsp_common.h"
      26             : #include "vpx_mem/vpx_mem.h"
      27             : #include "vpx_ports/system_state.h"
      28             : #if CONFIG_ERROR_CONCEALMENT
      29             : #include "decoder/error_concealment.h"
      30             : #endif
      31             : #include "decoder/decoderthreading.h"
      32             : 
      33             : #define VP8_CAP_POSTPROC (CONFIG_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0)
      34             : #define VP8_CAP_ERROR_CONCEALMENT \
      35             :   (CONFIG_ERROR_CONCEALMENT ? VPX_CODEC_CAP_ERROR_CONCEALMENT : 0)
      36             : 
      37             : typedef vpx_codec_stream_info_t vp8_stream_info_t;
      38             : 
      39             : /* Structures for handling memory allocations */
      40             : typedef enum { VP8_SEG_ALG_PRIV = 256, VP8_SEG_MAX } mem_seg_id_t;
      41             : #define NELEMENTS(x) ((int)(sizeof(x) / sizeof(x[0])))
      42             : 
      43             : struct vpx_codec_alg_priv {
      44             :   vpx_codec_priv_t base;
      45             :   vpx_codec_dec_cfg_t cfg;
      46             :   vp8_stream_info_t si;
      47             :   int decoder_init;
      48             :   int postproc_cfg_set;
      49             :   vp8_postproc_cfg_t postproc_cfg;
      50             :   vpx_decrypt_cb decrypt_cb;
      51             :   void *decrypt_state;
      52             :   vpx_image_t img;
      53             :   int img_setup;
      54             :   struct frame_buffers yv12_frame_buffers;
      55             :   void *user_priv;
      56             :   FRAGMENT_DATA fragments;
      57             : };
      58             : 
      59           0 : static int vp8_init_ctx(vpx_codec_ctx_t *ctx) {
      60           0 :   vpx_codec_alg_priv_t *priv =
      61             :       (vpx_codec_alg_priv_t *)vpx_calloc(1, sizeof(*priv));
      62           0 :   if (!priv) return 1;
      63             : 
      64           0 :   ctx->priv = (vpx_codec_priv_t *)priv;
      65           0 :   ctx->priv->init_flags = ctx->init_flags;
      66             : 
      67           0 :   priv->si.sz = sizeof(priv->si);
      68           0 :   priv->decrypt_cb = NULL;
      69           0 :   priv->decrypt_state = NULL;
      70             : 
      71           0 :   if (ctx->config.dec) {
      72             :     /* Update the reference to the config structure to an internal copy. */
      73           0 :     priv->cfg = *ctx->config.dec;
      74           0 :     ctx->config.dec = &priv->cfg;
      75             :   }
      76             : 
      77           0 :   return 0;
      78             : }
      79             : 
      80           0 : static vpx_codec_err_t vp8_init(vpx_codec_ctx_t *ctx,
      81             :                                 vpx_codec_priv_enc_mr_cfg_t *data) {
      82           0 :   vpx_codec_err_t res = VPX_CODEC_OK;
      83           0 :   vpx_codec_alg_priv_t *priv = NULL;
      84             :   (void)data;
      85             : 
      86           0 :   vp8_rtcd();
      87           0 :   vpx_dsp_rtcd();
      88           0 :   vpx_scale_rtcd();
      89             : 
      90             :   /* This function only allocates space for the vpx_codec_alg_priv_t
      91             :    * structure. More memory may be required at the time the stream
      92             :    * information becomes known.
      93             :    */
      94           0 :   if (!ctx->priv) {
      95           0 :     if (vp8_init_ctx(ctx)) return VPX_CODEC_MEM_ERROR;
      96           0 :     priv = (vpx_codec_alg_priv_t *)ctx->priv;
      97             : 
      98             :     /* initialize number of fragments to zero */
      99           0 :     priv->fragments.count = 0;
     100             :     /* is input fragments enabled? */
     101           0 :     priv->fragments.enabled =
     102           0 :         (priv->base.init_flags & VPX_CODEC_USE_INPUT_FRAGMENTS);
     103             : 
     104             :     /*post processing level initialized to do nothing */
     105             :   } else {
     106           0 :     priv = (vpx_codec_alg_priv_t *)ctx->priv;
     107             :   }
     108             : 
     109           0 :   return res;
     110             : }
     111             : 
     112           0 : static vpx_codec_err_t vp8_destroy(vpx_codec_alg_priv_t *ctx) {
     113           0 :   vp8_remove_decoder_instances(&ctx->yv12_frame_buffers);
     114             : 
     115           0 :   vpx_free(ctx);
     116             : 
     117           0 :   return VPX_CODEC_OK;
     118             : }
     119             : 
     120           0 : static vpx_codec_err_t vp8_peek_si_internal(const uint8_t *data,
     121             :                                             unsigned int data_sz,
     122             :                                             vpx_codec_stream_info_t *si,
     123             :                                             vpx_decrypt_cb decrypt_cb,
     124             :                                             void *decrypt_state) {
     125           0 :   vpx_codec_err_t res = VPX_CODEC_OK;
     126             : 
     127           0 :   assert(data != NULL);
     128             : 
     129           0 :   if (data + data_sz <= data) {
     130           0 :     res = VPX_CODEC_INVALID_PARAM;
     131             :   } else {
     132             :     /* Parse uncompresssed part of key frame header.
     133             :      * 3 bytes:- including version, frame type and an offset
     134             :      * 3 bytes:- sync code (0x9d, 0x01, 0x2a)
     135             :      * 4 bytes:- including image width and height in the lowest 14 bits
     136             :      *           of each 2-byte value.
     137             :      */
     138             :     uint8_t clear_buffer[10];
     139           0 :     const uint8_t *clear = data;
     140           0 :     if (decrypt_cb) {
     141           0 :       int n = VPXMIN(sizeof(clear_buffer), data_sz);
     142           0 :       decrypt_cb(decrypt_state, data, clear_buffer, n);
     143           0 :       clear = clear_buffer;
     144             :     }
     145           0 :     si->is_kf = 0;
     146             : 
     147           0 :     if (data_sz >= 10 && !(clear[0] & 0x01)) /* I-Frame */
     148             :     {
     149           0 :       si->is_kf = 1;
     150             : 
     151             :       /* vet via sync code */
     152           0 :       if (clear[3] != 0x9d || clear[4] != 0x01 || clear[5] != 0x2a) {
     153           0 :         return VPX_CODEC_UNSUP_BITSTREAM;
     154             :       }
     155             : 
     156           0 :       si->w = (clear[6] | (clear[7] << 8)) & 0x3fff;
     157           0 :       si->h = (clear[8] | (clear[9] << 8)) & 0x3fff;
     158             : 
     159             :       /*printf("w=%d, h=%d\n", si->w, si->h);*/
     160           0 :       if (!(si->h && si->w)) res = VPX_CODEC_CORRUPT_FRAME;
     161             :     } else {
     162           0 :       res = VPX_CODEC_UNSUP_BITSTREAM;
     163             :     }
     164             :   }
     165             : 
     166           0 :   return res;
     167             : }
     168             : 
     169           0 : static vpx_codec_err_t vp8_peek_si(const uint8_t *data, unsigned int data_sz,
     170             :                                    vpx_codec_stream_info_t *si) {
     171           0 :   return vp8_peek_si_internal(data, data_sz, si, NULL, NULL);
     172             : }
     173             : 
     174           0 : static vpx_codec_err_t vp8_get_si(vpx_codec_alg_priv_t *ctx,
     175             :                                   vpx_codec_stream_info_t *si) {
     176             :   unsigned int sz;
     177             : 
     178           0 :   if (si->sz >= sizeof(vp8_stream_info_t)) {
     179           0 :     sz = sizeof(vp8_stream_info_t);
     180             :   } else {
     181           0 :     sz = sizeof(vpx_codec_stream_info_t);
     182             :   }
     183             : 
     184           0 :   memcpy(si, &ctx->si, sz);
     185           0 :   si->sz = sz;
     186             : 
     187           0 :   return VPX_CODEC_OK;
     188             : }
     189             : 
     190           0 : static vpx_codec_err_t update_error_state(
     191             :     vpx_codec_alg_priv_t *ctx, const struct vpx_internal_error_info *error) {
     192             :   vpx_codec_err_t res;
     193             : 
     194           0 :   if ((res = error->error_code)) {
     195           0 :     ctx->base.err_detail = error->has_detail ? error->detail : NULL;
     196             :   }
     197             : 
     198           0 :   return res;
     199             : }
     200             : 
     201           0 : static void yuvconfig2image(vpx_image_t *img, const YV12_BUFFER_CONFIG *yv12,
     202             :                             void *user_priv) {
     203             :   /** vpx_img_wrap() doesn't allow specifying independent strides for
     204             :     * the Y, U, and V planes, nor other alignment adjustments that
     205             :     * might be representable by a YV12_BUFFER_CONFIG, so we just
     206             :     * initialize all the fields.*/
     207           0 :   img->fmt = VPX_IMG_FMT_I420;
     208           0 :   img->w = yv12->y_stride;
     209           0 :   img->h = (yv12->y_height + 2 * VP8BORDERINPIXELS + 15) & ~15;
     210           0 :   img->d_w = img->r_w = yv12->y_width;
     211           0 :   img->d_h = img->r_h = yv12->y_height;
     212           0 :   img->x_chroma_shift = 1;
     213           0 :   img->y_chroma_shift = 1;
     214           0 :   img->planes[VPX_PLANE_Y] = yv12->y_buffer;
     215           0 :   img->planes[VPX_PLANE_U] = yv12->u_buffer;
     216           0 :   img->planes[VPX_PLANE_V] = yv12->v_buffer;
     217           0 :   img->planes[VPX_PLANE_ALPHA] = NULL;
     218           0 :   img->stride[VPX_PLANE_Y] = yv12->y_stride;
     219           0 :   img->stride[VPX_PLANE_U] = yv12->uv_stride;
     220           0 :   img->stride[VPX_PLANE_V] = yv12->uv_stride;
     221           0 :   img->stride[VPX_PLANE_ALPHA] = yv12->y_stride;
     222           0 :   img->bit_depth = 8;
     223           0 :   img->bps = 12;
     224           0 :   img->user_priv = user_priv;
     225           0 :   img->img_data = yv12->buffer_alloc;
     226           0 :   img->img_data_owner = 0;
     227           0 :   img->self_allocd = 0;
     228           0 : }
     229             : 
     230           0 : static int update_fragments(vpx_codec_alg_priv_t *ctx, const uint8_t *data,
     231             :                             unsigned int data_sz, vpx_codec_err_t *res) {
     232           0 :   *res = VPX_CODEC_OK;
     233             : 
     234           0 :   if (ctx->fragments.count == 0) {
     235             :     /* New frame, reset fragment pointers and sizes */
     236           0 :     memset((void *)ctx->fragments.ptrs, 0, sizeof(ctx->fragments.ptrs));
     237           0 :     memset(ctx->fragments.sizes, 0, sizeof(ctx->fragments.sizes));
     238             :   }
     239           0 :   if (ctx->fragments.enabled && !(data == NULL && data_sz == 0)) {
     240             :     /* Store a pointer to this fragment and return. We haven't
     241             :      * received the complete frame yet, so we will wait with decoding.
     242             :      */
     243           0 :     ctx->fragments.ptrs[ctx->fragments.count] = data;
     244           0 :     ctx->fragments.sizes[ctx->fragments.count] = data_sz;
     245           0 :     ctx->fragments.count++;
     246           0 :     if (ctx->fragments.count > (1 << EIGHT_PARTITION) + 1) {
     247           0 :       ctx->fragments.count = 0;
     248           0 :       *res = VPX_CODEC_INVALID_PARAM;
     249           0 :       return -1;
     250             :     }
     251           0 :     return 0;
     252             :   }
     253             : 
     254           0 :   if (!ctx->fragments.enabled && (data == NULL && data_sz == 0)) {
     255           0 :     return 0;
     256             :   }
     257             : 
     258           0 :   if (!ctx->fragments.enabled) {
     259           0 :     ctx->fragments.ptrs[0] = data;
     260           0 :     ctx->fragments.sizes[0] = data_sz;
     261           0 :     ctx->fragments.count = 1;
     262             :   }
     263             : 
     264           0 :   return 1;
     265             : }
     266             : 
     267           0 : static vpx_codec_err_t vp8_decode(vpx_codec_alg_priv_t *ctx,
     268             :                                   const uint8_t *data, unsigned int data_sz,
     269             :                                   void *user_priv, long deadline) {
     270           0 :   vpx_codec_err_t res = VPX_CODEC_OK;
     271           0 :   unsigned int resolution_change = 0;
     272             :   unsigned int w, h;
     273             : 
     274           0 :   if (!ctx->fragments.enabled && (data == NULL && data_sz == 0)) {
     275           0 :     return 0;
     276             :   }
     277             : 
     278             :   /* Update the input fragment data */
     279           0 :   if (update_fragments(ctx, data, data_sz, &res) <= 0) return res;
     280             : 
     281             :   /* Determine the stream parameters. Note that we rely on peek_si to
     282             :    * validate that we have a buffer that does not wrap around the top
     283             :    * of the heap.
     284             :    */
     285           0 :   w = ctx->si.w;
     286           0 :   h = ctx->si.h;
     287             : 
     288           0 :   res = vp8_peek_si_internal(ctx->fragments.ptrs[0], ctx->fragments.sizes[0],
     289           0 :                              &ctx->si, ctx->decrypt_cb, ctx->decrypt_state);
     290             : 
     291           0 :   if ((res == VPX_CODEC_UNSUP_BITSTREAM) && !ctx->si.is_kf) {
     292             :     /* the peek function returns an error for non keyframes, however for
     293             :      * this case, it is not an error */
     294           0 :     res = VPX_CODEC_OK;
     295             :   }
     296             : 
     297           0 :   if (!ctx->decoder_init && !ctx->si.is_kf) res = VPX_CODEC_UNSUP_BITSTREAM;
     298             : 
     299           0 :   if ((ctx->si.h != h) || (ctx->si.w != w)) resolution_change = 1;
     300             : 
     301             :   /* Initialize the decoder instance on the first frame*/
     302           0 :   if (!res && !ctx->decoder_init) {
     303             :     VP8D_CONFIG oxcf;
     304             : 
     305           0 :     oxcf.Width = ctx->si.w;
     306           0 :     oxcf.Height = ctx->si.h;
     307           0 :     oxcf.Version = 9;
     308           0 :     oxcf.postprocess = 0;
     309           0 :     oxcf.max_threads = ctx->cfg.threads;
     310           0 :     oxcf.error_concealment =
     311           0 :         (ctx->base.init_flags & VPX_CODEC_USE_ERROR_CONCEALMENT);
     312             : 
     313             :     /* If postprocessing was enabled by the application and a
     314             :      * configuration has not been provided, default it.
     315             :      */
     316           0 :     if (!ctx->postproc_cfg_set &&
     317           0 :         (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) {
     318           0 :       ctx->postproc_cfg.post_proc_flag =
     319             :           VP8_DEBLOCK | VP8_DEMACROBLOCK | VP8_MFQE;
     320           0 :       ctx->postproc_cfg.deblocking_level = 4;
     321           0 :       ctx->postproc_cfg.noise_level = 0;
     322             :     }
     323             : 
     324           0 :     res = vp8_create_decoder_instances(&ctx->yv12_frame_buffers, &oxcf);
     325           0 :     if (res == VPX_CODEC_OK) ctx->decoder_init = 1;
     326             :   }
     327             : 
     328             :   /* Set these even if already initialized.  The caller may have changed the
     329             :    * decrypt config between frames.
     330             :    */
     331           0 :   if (ctx->decoder_init) {
     332           0 :     ctx->yv12_frame_buffers.pbi[0]->decrypt_cb = ctx->decrypt_cb;
     333           0 :     ctx->yv12_frame_buffers.pbi[0]->decrypt_state = ctx->decrypt_state;
     334             :   }
     335             : 
     336           0 :   if (!res) {
     337           0 :     VP8D_COMP *pbi = ctx->yv12_frame_buffers.pbi[0];
     338           0 :     if (resolution_change) {
     339           0 :       VP8_COMMON *const pc = &pbi->common;
     340           0 :       MACROBLOCKD *const xd = &pbi->mb;
     341             : #if CONFIG_MULTITHREAD
     342             :       int i;
     343             : #endif
     344           0 :       pc->Width = ctx->si.w;
     345           0 :       pc->Height = ctx->si.h;
     346             :       {
     347           0 :         int prev_mb_rows = pc->mb_rows;
     348             : 
     349           0 :         if (setjmp(pbi->common.error.jmp)) {
     350           0 :           pbi->common.error.setjmp = 0;
     351             :           /* on failure clear the cached resolution to ensure a full
     352             :            * reallocation is attempted on resync. */
     353           0 :           ctx->si.w = 0;
     354           0 :           ctx->si.h = 0;
     355           0 :           vpx_clear_system_state();
     356             :           /* same return value as used in vp8dx_receive_compressed_data */
     357           0 :           return -1;
     358             :         }
     359             : 
     360           0 :         pbi->common.error.setjmp = 1;
     361             : 
     362           0 :         if (pc->Width <= 0) {
     363           0 :           pc->Width = w;
     364           0 :           vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
     365             :                              "Invalid frame width");
     366             :         }
     367             : 
     368           0 :         if (pc->Height <= 0) {
     369           0 :           pc->Height = h;
     370           0 :           vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
     371             :                              "Invalid frame height");
     372             :         }
     373             : 
     374           0 :         if (vp8_alloc_frame_buffers(pc, pc->Width, pc->Height)) {
     375           0 :           vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
     376             :                              "Failed to allocate frame buffers");
     377             :         }
     378             : 
     379           0 :         xd->pre = pc->yv12_fb[pc->lst_fb_idx];
     380           0 :         xd->dst = pc->yv12_fb[pc->new_fb_idx];
     381             : 
     382             : #if CONFIG_MULTITHREAD
     383           0 :         for (i = 0; i < pbi->allocated_decoding_thread_count; ++i) {
     384           0 :           pbi->mb_row_di[i].mbd.dst = pc->yv12_fb[pc->new_fb_idx];
     385           0 :           vp8_build_block_doffsets(&pbi->mb_row_di[i].mbd);
     386             :         }
     387             : #endif
     388           0 :         vp8_build_block_doffsets(&pbi->mb);
     389             : 
     390             : /* allocate memory for last frame MODE_INFO array */
     391             : #if CONFIG_ERROR_CONCEALMENT
     392             : 
     393             :         if (pbi->ec_enabled) {
     394             :           /* old prev_mip was released by vp8_de_alloc_frame_buffers()
     395             :            * called in vp8_alloc_frame_buffers() */
     396             :           pc->prev_mip = vpx_calloc((pc->mb_cols + 1) * (pc->mb_rows + 1),
     397             :                                     sizeof(MODE_INFO));
     398             : 
     399             :           if (!pc->prev_mip) {
     400             :             vp8_de_alloc_frame_buffers(pc);
     401             :             vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
     402             :                                "Failed to allocate"
     403             :                                "last frame MODE_INFO array");
     404             :           }
     405             : 
     406             :           pc->prev_mi = pc->prev_mip + pc->mode_info_stride + 1;
     407             : 
     408             :           if (vp8_alloc_overlap_lists(pbi))
     409             :             vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
     410             :                                "Failed to allocate overlap lists "
     411             :                                "for error concealment");
     412             :         }
     413             : 
     414             : #endif
     415             : 
     416             : #if CONFIG_MULTITHREAD
     417           0 :         if (pbi->b_multithreaded_rd) {
     418           0 :           vp8mt_alloc_temp_buffers(pbi, pc->Width, prev_mb_rows);
     419             :         }
     420             : #else
     421             :         (void)prev_mb_rows;
     422             : #endif
     423             :       }
     424             : 
     425           0 :       pbi->common.error.setjmp = 0;
     426             : 
     427             :       /* required to get past the first get_free_fb() call */
     428           0 :       pbi->common.fb_idx_ref_cnt[0] = 0;
     429             :     }
     430             : 
     431             :     /* update the pbi fragment data */
     432           0 :     pbi->fragments = ctx->fragments;
     433             : 
     434           0 :     ctx->user_priv = user_priv;
     435           0 :     if (vp8dx_receive_compressed_data(pbi, data_sz, data, deadline)) {
     436           0 :       res = update_error_state(ctx, &pbi->common.error);
     437             :     }
     438             : 
     439             :     /* get ready for the next series of fragments */
     440           0 :     ctx->fragments.count = 0;
     441             :   }
     442             : 
     443           0 :   return res;
     444             : }
     445             : 
     446           0 : static vpx_image_t *vp8_get_frame(vpx_codec_alg_priv_t *ctx,
     447             :                                   vpx_codec_iter_t *iter) {
     448           0 :   vpx_image_t *img = NULL;
     449             : 
     450             :   /* iter acts as a flip flop, so an image is only returned on the first
     451             :    * call to get_frame.
     452             :    */
     453           0 :   if (!(*iter) && ctx->yv12_frame_buffers.pbi[0]) {
     454             :     YV12_BUFFER_CONFIG sd;
     455           0 :     int64_t time_stamp = 0, time_end_stamp = 0;
     456             :     vp8_ppflags_t flags;
     457           0 :     vp8_zero(flags);
     458             : 
     459           0 :     if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC) {
     460           0 :       flags.post_proc_flag = ctx->postproc_cfg.post_proc_flag;
     461           0 :       flags.deblocking_level = ctx->postproc_cfg.deblocking_level;
     462           0 :       flags.noise_level = ctx->postproc_cfg.noise_level;
     463             :     }
     464             : 
     465           0 :     if (0 == vp8dx_get_raw_frame(ctx->yv12_frame_buffers.pbi[0], &sd,
     466             :                                  &time_stamp, &time_end_stamp, &flags)) {
     467           0 :       yuvconfig2image(&ctx->img, &sd, ctx->user_priv);
     468             : 
     469           0 :       img = &ctx->img;
     470           0 :       *iter = img;
     471             :     }
     472             :   }
     473             : 
     474           0 :   return img;
     475             : }
     476             : 
     477           0 : static vpx_codec_err_t image2yuvconfig(const vpx_image_t *img,
     478             :                                        YV12_BUFFER_CONFIG *yv12) {
     479           0 :   const int y_w = img->d_w;
     480           0 :   const int y_h = img->d_h;
     481           0 :   const int uv_w = (img->d_w + 1) / 2;
     482           0 :   const int uv_h = (img->d_h + 1) / 2;
     483           0 :   vpx_codec_err_t res = VPX_CODEC_OK;
     484           0 :   yv12->y_buffer = img->planes[VPX_PLANE_Y];
     485           0 :   yv12->u_buffer = img->planes[VPX_PLANE_U];
     486           0 :   yv12->v_buffer = img->planes[VPX_PLANE_V];
     487             : 
     488           0 :   yv12->y_crop_width = y_w;
     489           0 :   yv12->y_crop_height = y_h;
     490           0 :   yv12->y_width = y_w;
     491           0 :   yv12->y_height = y_h;
     492           0 :   yv12->uv_crop_width = uv_w;
     493           0 :   yv12->uv_crop_height = uv_h;
     494           0 :   yv12->uv_width = uv_w;
     495           0 :   yv12->uv_height = uv_h;
     496             : 
     497           0 :   yv12->y_stride = img->stride[VPX_PLANE_Y];
     498           0 :   yv12->uv_stride = img->stride[VPX_PLANE_U];
     499             : 
     500           0 :   yv12->border = (img->stride[VPX_PLANE_Y] - img->d_w) / 2;
     501           0 :   return res;
     502             : }
     503             : 
     504           0 : static vpx_codec_err_t vp8_set_reference(vpx_codec_alg_priv_t *ctx,
     505             :                                          va_list args) {
     506           0 :   vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *);
     507             : 
     508           0 :   if (data) {
     509           0 :     vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data;
     510             :     YV12_BUFFER_CONFIG sd;
     511             : 
     512           0 :     image2yuvconfig(&frame->img, &sd);
     513             : 
     514           0 :     return vp8dx_set_reference(ctx->yv12_frame_buffers.pbi[0],
     515             :                                frame->frame_type, &sd);
     516             :   } else {
     517           0 :     return VPX_CODEC_INVALID_PARAM;
     518             :   }
     519             : }
     520             : 
     521           0 : static vpx_codec_err_t vp8_get_reference(vpx_codec_alg_priv_t *ctx,
     522             :                                          va_list args) {
     523           0 :   vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *);
     524             : 
     525           0 :   if (data) {
     526           0 :     vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data;
     527             :     YV12_BUFFER_CONFIG sd;
     528             : 
     529           0 :     image2yuvconfig(&frame->img, &sd);
     530             : 
     531           0 :     return vp8dx_get_reference(ctx->yv12_frame_buffers.pbi[0],
     532             :                                frame->frame_type, &sd);
     533             :   } else {
     534           0 :     return VPX_CODEC_INVALID_PARAM;
     535             :   }
     536             : }
     537             : 
     538           0 : static vpx_codec_err_t vp8_set_postproc(vpx_codec_alg_priv_t *ctx,
     539             :                                         va_list args) {
     540             : #if CONFIG_POSTPROC
     541           0 :   vp8_postproc_cfg_t *data = va_arg(args, vp8_postproc_cfg_t *);
     542             : 
     543           0 :   if (data) {
     544           0 :     ctx->postproc_cfg_set = 1;
     545           0 :     ctx->postproc_cfg = *((vp8_postproc_cfg_t *)data);
     546           0 :     return VPX_CODEC_OK;
     547             :   } else {
     548           0 :     return VPX_CODEC_INVALID_PARAM;
     549             :   }
     550             : 
     551             : #else
     552             :   (void)ctx;
     553             :   (void)args;
     554             :   return VPX_CODEC_INCAPABLE;
     555             : #endif
     556             : }
     557             : 
     558           0 : static vpx_codec_err_t vp8_get_last_ref_updates(vpx_codec_alg_priv_t *ctx,
     559             :                                                 va_list args) {
     560           0 :   int *update_info = va_arg(args, int *);
     561             : 
     562           0 :   if (update_info) {
     563           0 :     VP8D_COMP *pbi = (VP8D_COMP *)ctx->yv12_frame_buffers.pbi[0];
     564             : 
     565           0 :     *update_info = pbi->common.refresh_alt_ref_frame * (int)VP8_ALTR_FRAME +
     566           0 :                    pbi->common.refresh_golden_frame * (int)VP8_GOLD_FRAME +
     567           0 :                    pbi->common.refresh_last_frame * (int)VP8_LAST_FRAME;
     568             : 
     569           0 :     return VPX_CODEC_OK;
     570             :   } else {
     571           0 :     return VPX_CODEC_INVALID_PARAM;
     572             :   }
     573             : }
     574             : 
     575             : extern int vp8dx_references_buffer(VP8_COMMON *oci, int ref_frame);
     576           0 : static vpx_codec_err_t vp8_get_last_ref_frame(vpx_codec_alg_priv_t *ctx,
     577             :                                               va_list args) {
     578           0 :   int *ref_info = va_arg(args, int *);
     579             : 
     580           0 :   if (ref_info) {
     581           0 :     VP8D_COMP *pbi = (VP8D_COMP *)ctx->yv12_frame_buffers.pbi[0];
     582           0 :     VP8_COMMON *oci = &pbi->common;
     583           0 :     *ref_info =
     584           0 :         (vp8dx_references_buffer(oci, ALTREF_FRAME) ? VP8_ALTR_FRAME : 0) |
     585           0 :         (vp8dx_references_buffer(oci, GOLDEN_FRAME) ? VP8_GOLD_FRAME : 0) |
     586           0 :         (vp8dx_references_buffer(oci, LAST_FRAME) ? VP8_LAST_FRAME : 0);
     587             : 
     588           0 :     return VPX_CODEC_OK;
     589             :   } else {
     590           0 :     return VPX_CODEC_INVALID_PARAM;
     591             :   }
     592             : }
     593             : 
     594           0 : static vpx_codec_err_t vp8_get_frame_corrupted(vpx_codec_alg_priv_t *ctx,
     595             :                                                va_list args) {
     596           0 :   int *corrupted = va_arg(args, int *);
     597           0 :   VP8D_COMP *pbi = (VP8D_COMP *)ctx->yv12_frame_buffers.pbi[0];
     598             : 
     599           0 :   if (corrupted && pbi) {
     600           0 :     const YV12_BUFFER_CONFIG *const frame = pbi->common.frame_to_show;
     601           0 :     if (frame == NULL) return VPX_CODEC_ERROR;
     602           0 :     *corrupted = frame->corrupted;
     603           0 :     return VPX_CODEC_OK;
     604             :   } else {
     605           0 :     return VPX_CODEC_INVALID_PARAM;
     606             :   }
     607             : }
     608             : 
     609           0 : static vpx_codec_err_t vp8_set_decryptor(vpx_codec_alg_priv_t *ctx,
     610             :                                          va_list args) {
     611           0 :   vpx_decrypt_init *init = va_arg(args, vpx_decrypt_init *);
     612             : 
     613           0 :   if (init) {
     614           0 :     ctx->decrypt_cb = init->decrypt_cb;
     615           0 :     ctx->decrypt_state = init->decrypt_state;
     616             :   } else {
     617           0 :     ctx->decrypt_cb = NULL;
     618           0 :     ctx->decrypt_state = NULL;
     619             :   }
     620           0 :   return VPX_CODEC_OK;
     621             : }
     622             : 
     623             : vpx_codec_ctrl_fn_map_t vp8_ctf_maps[] = {
     624             :   { VP8_SET_REFERENCE, vp8_set_reference },
     625             :   { VP8_COPY_REFERENCE, vp8_get_reference },
     626             :   { VP8_SET_POSTPROC, vp8_set_postproc },
     627             :   { VP8D_GET_LAST_REF_UPDATES, vp8_get_last_ref_updates },
     628             :   { VP8D_GET_FRAME_CORRUPTED, vp8_get_frame_corrupted },
     629             :   { VP8D_GET_LAST_REF_USED, vp8_get_last_ref_frame },
     630             :   { VPXD_SET_DECRYPTOR, vp8_set_decryptor },
     631             :   { -1, NULL },
     632             : };
     633             : 
     634             : #ifndef VERSION_STRING
     635             : #define VERSION_STRING
     636             : #endif
     637           0 : CODEC_INTERFACE(vpx_codec_vp8_dx) = {
     638             :   "WebM Project VP8 Decoder" VERSION_STRING,
     639             :   VPX_CODEC_INTERNAL_ABI_VERSION,
     640             :   VPX_CODEC_CAP_DECODER | VP8_CAP_POSTPROC | VP8_CAP_ERROR_CONCEALMENT |
     641             :       VPX_CODEC_CAP_INPUT_FRAGMENTS,
     642             :   /* vpx_codec_caps_t          caps; */
     643             :   vp8_init,     /* vpx_codec_init_fn_t       init; */
     644             :   vp8_destroy,  /* vpx_codec_destroy_fn_t    destroy; */
     645             :   vp8_ctf_maps, /* vpx_codec_ctrl_fn_map_t  *ctrl_maps; */
     646             :   {
     647             :       vp8_peek_si,   /* vpx_codec_peek_si_fn_t    peek_si; */
     648             :       vp8_get_si,    /* vpx_codec_get_si_fn_t     get_si; */
     649             :       vp8_decode,    /* vpx_codec_decode_fn_t     decode; */
     650             :       vp8_get_frame, /* vpx_codec_frame_get_fn_t  frame_get; */
     651             :       NULL,
     652             :   },
     653             :   {
     654             :       /* encoder functions */
     655             :       0, NULL, /* vpx_codec_enc_cfg_map_t */
     656             :       NULL,    /* vpx_codec_encode_fn_t */
     657             :       NULL,    /* vpx_codec_get_cx_data_fn_t */
     658             :       NULL,    /* vpx_codec_enc_config_set_fn_t */
     659             :       NULL,    /* vpx_codec_get_global_headers_fn_t */
     660             :       NULL,    /* vpx_codec_get_preview_frame_fn_t */
     661             :       NULL     /* vpx_codec_enc_mr_get_mem_loc_fn_t */
     662             :   }
     663             : };

Generated by: LCOV version 1.13