~ubuntu-branches/ubuntu/vivid/gstreamer-vaapi/vivid

« back to all changes in this revision

Viewing changes to ext/libvpx/upstream/vp9/vp9_dx_iface.c

  • Committer: Package Import Robot
  • Author(s): Vincent Cheng
  • Date: 2014-08-06 23:56:00 UTC
  • mfrom: (0.1.4 sid) (1.1.3)
  • Revision ID: package-import@ubuntu.com-20140806235600-fg1kcmiu67k315q5
Tags: 0.5.9-2
* Remove spurious build-deps: libva-drm1, libavcodec-dev. (Closes: #757283)
* Drop Build-Depends-Indep and build docs unconditionally on all archs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
12
#include <stdlib.h>
 
13
#include <string.h>
 
14
#include "vpx/vpx_decoder.h"
 
15
#include "vpx/vp8dx.h"
 
16
#include "vpx/internal/vpx_codec_internal.h"
 
17
#include "./vpx_version.h"
 
18
#include "vp9/decoder/vp9_onyxd.h"
 
19
#include "vp9/decoder/vp9_onyxd_int.h"
 
20
#include "vp9/decoder/vp9_read_bit_buffer.h"
 
21
#include "vp9/vp9_iface_common.h"
 
22
 
 
23
#define VP9_CAP_POSTPROC (CONFIG_VP9_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0)
 
24
typedef vpx_codec_stream_info_t  vp9_stream_info_t;
 
25
 
 
26
/* Structures for handling memory allocations */
 
27
typedef enum {
 
28
  VP9_SEG_ALG_PRIV     = 256,
 
29
  VP9_SEG_MAX
 
30
} mem_seg_id_t;
 
31
#define NELEMENTS(x) ((int)(sizeof(x)/sizeof(x[0])))
 
32
 
 
33
static unsigned long priv_sz(const vpx_codec_dec_cfg_t *si,
 
34
                             vpx_codec_flags_t flags);
 
35
 
 
36
static const mem_req_t vp9_mem_req_segs[] = {
 
37
  {VP9_SEG_ALG_PRIV, 0, 8, VPX_CODEC_MEM_ZERO, priv_sz},
 
38
  {VP9_SEG_MAX, 0, 0, 0, NULL}
 
39
};
 
40
 
 
41
struct vpx_codec_alg_priv {
 
42
  vpx_codec_priv_t        base;
 
43
  vpx_codec_mmap_t        mmaps[NELEMENTS(vp9_mem_req_segs) - 1];
 
44
  vpx_codec_dec_cfg_t     cfg;
 
45
  vp9_stream_info_t       si;
 
46
  int                     defer_alloc;
 
47
  int                     decoder_init;
 
48
  VP9D_PTR                pbi;
 
49
  int                     postproc_cfg_set;
 
50
  vp8_postproc_cfg_t      postproc_cfg;
 
51
#if CONFIG_POSTPROC_VISUALIZER
 
52
  unsigned int            dbg_postproc_flag;
 
53
  int                     dbg_color_ref_frame_flag;
 
54
  int                     dbg_color_mb_modes_flag;
 
55
  int                     dbg_color_b_modes_flag;
 
56
  int                     dbg_display_mv_flag;
 
57
#endif
 
58
  vpx_image_t             img;
 
59
  int                     img_setup;
 
60
  int                     img_avail;
 
61
  int                     invert_tile_order;
 
62
};
 
63
 
 
64
static unsigned long priv_sz(const vpx_codec_dec_cfg_t *si,
 
65
                             vpx_codec_flags_t flags) {
 
66
  /* Although this declaration is constant, we can't use it in the requested
 
67
   * segments list because we want to define the requested segments list
 
68
   * before defining the private type (so that the number of memory maps is
 
69
   * known)
 
70
   */
 
71
  (void)si;
 
72
  return sizeof(vpx_codec_alg_priv_t);
 
73
}
 
74
 
 
75
static void vp9_init_ctx(vpx_codec_ctx_t *ctx, const vpx_codec_mmap_t *mmap) {
 
76
  int i;
 
77
 
 
78
  ctx->priv = mmap->base;
 
79
  ctx->priv->sz = sizeof(*ctx->priv);
 
80
  ctx->priv->iface = ctx->iface;
 
81
  ctx->priv->alg_priv = mmap->base;
 
82
 
 
83
  for (i = 0; i < NELEMENTS(ctx->priv->alg_priv->mmaps); i++)
 
84
    ctx->priv->alg_priv->mmaps[i].id = vp9_mem_req_segs[i].id;
 
85
 
 
86
  ctx->priv->alg_priv->mmaps[0] = *mmap;
 
87
  ctx->priv->alg_priv->si.sz = sizeof(ctx->priv->alg_priv->si);
 
88
  ctx->priv->init_flags = ctx->init_flags;
 
89
 
 
90
  if (ctx->config.dec) {
 
91
    /* Update the reference to the config structure to an internal copy. */
 
92
    ctx->priv->alg_priv->cfg = *ctx->config.dec;
 
93
    ctx->config.dec = &ctx->priv->alg_priv->cfg;
 
94
  }
 
95
}
 
96
 
 
97
static void vp9_finalize_mmaps(vpx_codec_alg_priv_t *ctx) {
 
98
  /* nothing to clean up */
 
99
}
 
100
 
 
101
static vpx_codec_err_t vp9_init(vpx_codec_ctx_t *ctx,
 
102
                                vpx_codec_priv_enc_mr_cfg_t *data) {
 
103
  vpx_codec_err_t        res = VPX_CODEC_OK;
 
104
 
 
105
  /* This function only allocates space for the vpx_codec_alg_priv_t
 
106
   * structure. More memory may be required at the time the stream
 
107
   * information becomes known.
 
108
   */
 
109
  if (!ctx->priv) {
 
110
    vpx_codec_mmap_t mmap;
 
111
 
 
112
    mmap.id = vp9_mem_req_segs[0].id;
 
113
    mmap.sz = sizeof(vpx_codec_alg_priv_t);
 
114
    mmap.align = vp9_mem_req_segs[0].align;
 
115
    mmap.flags = vp9_mem_req_segs[0].flags;
 
116
 
 
117
    res = vpx_mmap_alloc(&mmap);
 
118
 
 
119
    if (!res) {
 
120
      vp9_init_ctx(ctx, &mmap);
 
121
 
 
122
      ctx->priv->alg_priv->defer_alloc = 1;
 
123
      /*post processing level initialized to do nothing */
 
124
    }
 
125
  }
 
126
 
 
127
  return res;
 
128
}
 
129
 
 
130
static vpx_codec_err_t vp9_destroy(vpx_codec_alg_priv_t *ctx) {
 
131
  int i;
 
132
 
 
133
  vp9_remove_decompressor(ctx->pbi);
 
134
 
 
135
  for (i = NELEMENTS(ctx->mmaps) - 1; i >= 0; i--) {
 
136
    if (ctx->mmaps[i].dtor)
 
137
      ctx->mmaps[i].dtor(&ctx->mmaps[i]);
 
138
  }
 
139
 
 
140
  return VPX_CODEC_OK;
 
141
}
 
142
 
 
143
static vpx_codec_err_t vp9_peek_si(const uint8_t         *data,
 
144
                                   unsigned int           data_sz,
 
145
                                   vpx_codec_stream_info_t *si) {
 
146
  if (data_sz <= 8) return VPX_CODEC_UNSUP_BITSTREAM;
 
147
  if (data + data_sz <= data) return VPX_CODEC_INVALID_PARAM;
 
148
 
 
149
  si->is_kf = 0;
 
150
  si->w = si->h = 0;
 
151
 
 
152
  {
 
153
    struct vp9_read_bit_buffer rb = { data, data + data_sz, 0, NULL, NULL };
 
154
    const int frame_marker = vp9_rb_read_literal(&rb, 2);
 
155
    const int version = vp9_rb_read_bit(&rb) | (vp9_rb_read_bit(&rb) << 1);
 
156
    if (frame_marker != 0x2) return VPX_CODEC_UNSUP_BITSTREAM;
 
157
#if CONFIG_NON420
 
158
    if (version > 1) return VPX_CODEC_UNSUP_BITSTREAM;
 
159
#else
 
160
    if (version != 0) return VPX_CODEC_UNSUP_BITSTREAM;
 
161
#endif
 
162
 
 
163
    if (vp9_rb_read_bit(&rb)) {  // show an existing frame
 
164
      return VPX_CODEC_OK;
 
165
    }
 
166
 
 
167
    si->is_kf = !vp9_rb_read_bit(&rb);
 
168
    if (si->is_kf) {
 
169
      const int sRGB = 7;
 
170
      int colorspace;
 
171
 
 
172
      rb.bit_offset += 1;  // show frame
 
173
      rb.bit_offset += 1;  // error resilient
 
174
 
 
175
      if (vp9_rb_read_literal(&rb, 8) != VP9_SYNC_CODE_0 ||
 
176
          vp9_rb_read_literal(&rb, 8) != VP9_SYNC_CODE_1 ||
 
177
          vp9_rb_read_literal(&rb, 8) != VP9_SYNC_CODE_2) {
 
178
        return VPX_CODEC_UNSUP_BITSTREAM;
 
179
      }
 
180
 
 
181
      colorspace = vp9_rb_read_literal(&rb, 3);
 
182
      if (colorspace != sRGB) {
 
183
        rb.bit_offset += 1;  // [16,235] (including xvycc) vs [0,255] range
 
184
        if (version == 1) {
 
185
          rb.bit_offset += 2;  // subsampling x/y
 
186
          rb.bit_offset += 1;  // has extra plane
 
187
        }
 
188
      } else {
 
189
        if (version == 1) {
 
190
          rb.bit_offset += 1;  // has extra plane
 
191
        } else {
 
192
          // RGB is only available in version 1
 
193
          return VPX_CODEC_UNSUP_BITSTREAM;
 
194
        }
 
195
      }
 
196
 
 
197
      // TODO(jzern): these are available on non-keyframes in intra only mode.
 
198
      si->w = vp9_rb_read_literal(&rb, 16) + 1;
 
199
      si->h = vp9_rb_read_literal(&rb, 16) + 1;
 
200
    }
 
201
  }
 
202
 
 
203
  return VPX_CODEC_OK;
 
204
}
 
205
 
 
206
static vpx_codec_err_t vp9_get_si(vpx_codec_alg_priv_t    *ctx,
 
207
                                  vpx_codec_stream_info_t *si) {
 
208
  unsigned int sz;
 
209
 
 
210
  if (si->sz >= sizeof(vp9_stream_info_t))
 
211
    sz = sizeof(vp9_stream_info_t);
 
212
  else
 
213
    sz = sizeof(vpx_codec_stream_info_t);
 
214
 
 
215
  memcpy(si, &ctx->si, sz);
 
216
  si->sz = sz;
 
217
 
 
218
  return VPX_CODEC_OK;
 
219
}
 
220
 
 
221
 
 
222
static vpx_codec_err_t
 
223
update_error_state(vpx_codec_alg_priv_t                 *ctx,
 
224
                   const struct vpx_internal_error_info *error) {
 
225
  vpx_codec_err_t res;
 
226
 
 
227
  if ((res = error->error_code))
 
228
    ctx->base.err_detail = error->has_detail
 
229
                           ? error->detail
 
230
                           : NULL;
 
231
 
 
232
  return res;
 
233
}
 
234
 
 
235
static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t  *ctx,
 
236
                                  const uint8_t        **data,
 
237
                                  unsigned int           data_sz,
 
238
                                  void                  *user_priv,
 
239
                                  long                   deadline) {
 
240
  vpx_codec_err_t res = VPX_CODEC_OK;
 
241
 
 
242
  ctx->img_avail = 0;
 
243
 
 
244
  /* Determine the stream parameters. Note that we rely on peek_si to
 
245
   * validate that we have a buffer that does not wrap around the top
 
246
   * of the heap.
 
247
   */
 
248
  if (!ctx->si.h)
 
249
    res = ctx->base.iface->dec.peek_si(*data, data_sz, &ctx->si);
 
250
 
 
251
 
 
252
  /* Perform deferred allocations, if required */
 
253
  if (!res && ctx->defer_alloc) {
 
254
    int i;
 
255
 
 
256
    for (i = 1; !res && i < NELEMENTS(ctx->mmaps); i++) {
 
257
      vpx_codec_dec_cfg_t cfg;
 
258
 
 
259
      cfg.w = ctx->si.w;
 
260
      cfg.h = ctx->si.h;
 
261
      ctx->mmaps[i].id = vp9_mem_req_segs[i].id;
 
262
      ctx->mmaps[i].sz = vp9_mem_req_segs[i].sz;
 
263
      ctx->mmaps[i].align = vp9_mem_req_segs[i].align;
 
264
      ctx->mmaps[i].flags = vp9_mem_req_segs[i].flags;
 
265
 
 
266
      if (!ctx->mmaps[i].sz)
 
267
        ctx->mmaps[i].sz = vp9_mem_req_segs[i].calc_sz(&cfg,
 
268
                                                       ctx->base.init_flags);
 
269
 
 
270
      res = vpx_mmap_alloc(&ctx->mmaps[i]);
 
271
    }
 
272
 
 
273
    if (!res)
 
274
      vp9_finalize_mmaps(ctx);
 
275
 
 
276
    ctx->defer_alloc = 0;
 
277
  }
 
278
 
 
279
  /* Initialize the decoder instance on the first frame*/
 
280
  if (!res && !ctx->decoder_init) {
 
281
    res = vpx_validate_mmaps(&ctx->si, ctx->mmaps,
 
282
                             vp9_mem_req_segs, NELEMENTS(vp9_mem_req_segs),
 
283
                             ctx->base.init_flags);
 
284
 
 
285
    if (!res) {
 
286
      VP9D_CONFIG oxcf;
 
287
      VP9D_PTR optr;
 
288
 
 
289
      vp9_initialize_dec();
 
290
 
 
291
      oxcf.width = ctx->si.w;
 
292
      oxcf.height = ctx->si.h;
 
293
      oxcf.version = 9;
 
294
      oxcf.postprocess = 0;
 
295
      oxcf.max_threads = ctx->cfg.threads;
 
296
      oxcf.inv_tile_order = ctx->invert_tile_order;
 
297
      optr = vp9_create_decompressor(&oxcf);
 
298
 
 
299
      /* If postprocessing was enabled by the application and a
 
300
       * configuration has not been provided, default it.
 
301
       */
 
302
      if (!ctx->postproc_cfg_set
 
303
          && (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) {
 
304
        ctx->postproc_cfg.post_proc_flag =
 
305
          VP8_DEBLOCK | VP8_DEMACROBLOCK;
 
306
        ctx->postproc_cfg.deblocking_level = 4;
 
307
        ctx->postproc_cfg.noise_level = 0;
 
308
      }
 
309
 
 
310
      if (!optr)
 
311
        res = VPX_CODEC_ERROR;
 
312
      else
 
313
        ctx->pbi = optr;
 
314
    }
 
315
 
 
316
    ctx->decoder_init = 1;
 
317
  }
 
318
 
 
319
  if (!res && ctx->pbi) {
 
320
    YV12_BUFFER_CONFIG sd;
 
321
    int64_t time_stamp = 0, time_end_stamp = 0;
 
322
    vp9_ppflags_t flags = {0};
 
323
 
 
324
    if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC) {
 
325
      flags.post_proc_flag =
 
326
#if CONFIG_POSTPROC_VISUALIZER
 
327
          ((ctx->dbg_color_ref_frame_flag != 0) ?
 
328
              VP9D_DEBUG_CLR_FRM_REF_BLKS : 0)
 
329
          | ((ctx->dbg_color_mb_modes_flag != 0) ?
 
330
              VP9D_DEBUG_CLR_BLK_MODES : 0)
 
331
          | ((ctx->dbg_color_b_modes_flag != 0) ?
 
332
              VP9D_DEBUG_CLR_BLK_MODES : 0)
 
333
          | ((ctx->dbg_display_mv_flag != 0) ?
 
334
              VP9D_DEBUG_DRAW_MV : 0)
 
335
          |
 
336
#endif
 
337
          ctx->postproc_cfg.post_proc_flag;
 
338
 
 
339
      flags.deblocking_level      = ctx->postproc_cfg.deblocking_level;
 
340
      flags.noise_level           = ctx->postproc_cfg.noise_level;
 
341
#if CONFIG_POSTPROC_VISUALIZER
 
342
      flags.display_ref_frame_flag = ctx->dbg_color_ref_frame_flag;
 
343
      flags.display_mb_modes_flag = ctx->dbg_color_mb_modes_flag;
 
344
      flags.display_b_modes_flag  = ctx->dbg_color_b_modes_flag;
 
345
      flags.display_mv_flag       = ctx->dbg_display_mv_flag;
 
346
#endif
 
347
    }
 
348
 
 
349
    if (vp9_receive_compressed_data(ctx->pbi, data_sz, data, deadline)) {
 
350
      VP9D_COMP *pbi = (VP9D_COMP *)ctx->pbi;
 
351
      res = update_error_state(ctx, &pbi->common.error);
 
352
    }
 
353
 
 
354
    if (!res && 0 == vp9_get_raw_frame(ctx->pbi, &sd, &time_stamp,
 
355
                                       &time_end_stamp, &flags)) {
 
356
      yuvconfig2image(&ctx->img, &sd, user_priv);
 
357
      ctx->img_avail = 1;
 
358
    }
 
359
  }
 
360
 
 
361
  return res;
 
362
}
 
363
 
 
364
static void parse_superframe_index(const uint8_t *data,
 
365
                                   size_t         data_sz,
 
366
                                   uint32_t       sizes[8],
 
367
                                   int           *count) {
 
368
  uint8_t marker;
 
369
 
 
370
  assert(data_sz);
 
371
  marker = data[data_sz - 1];
 
372
  *count = 0;
 
373
 
 
374
  if ((marker & 0xe0) == 0xc0) {
 
375
    const uint32_t frames = (marker & 0x7) + 1;
 
376
    const uint32_t mag = ((marker >> 3) & 0x3) + 1;
 
377
    const size_t index_sz = 2 + mag * frames;
 
378
 
 
379
    if (data_sz >= index_sz && data[data_sz - index_sz] == marker) {
 
380
      // found a valid superframe index
 
381
      uint32_t i, j;
 
382
      const uint8_t *x = data + data_sz - index_sz + 1;
 
383
 
 
384
      for (i = 0; i < frames; i++) {
 
385
        uint32_t this_sz = 0;
 
386
 
 
387
        for (j = 0; j < mag; j++)
 
388
          this_sz |= (*x++) << (j * 8);
 
389
        sizes[i] = this_sz;
 
390
      }
 
391
 
 
392
      *count = frames;
 
393
    }
 
394
  }
 
395
}
 
396
 
 
397
static vpx_codec_err_t vp9_decode(vpx_codec_alg_priv_t  *ctx,
 
398
                                  const uint8_t         *data,
 
399
                                  unsigned int           data_sz,
 
400
                                  void                  *user_priv,
 
401
                                  long                   deadline) {
 
402
  const uint8_t *data_start = data;
 
403
  const uint8_t *data_end = data + data_sz;
 
404
  vpx_codec_err_t res = 0;
 
405
  uint32_t sizes[8];
 
406
  int frames_this_pts, frame_count = 0;
 
407
 
 
408
  if (data == NULL || data_sz == 0) return VPX_CODEC_INVALID_PARAM;
 
409
 
 
410
  parse_superframe_index(data, data_sz, sizes, &frames_this_pts);
 
411
 
 
412
  do {
 
413
    // Skip over the superframe index, if present
 
414
    if (data_sz && (*data_start & 0xe0) == 0xc0) {
 
415
      const uint8_t marker = *data_start;
 
416
      const uint32_t frames = (marker & 0x7) + 1;
 
417
      const uint32_t mag = ((marker >> 3) & 0x3) + 1;
 
418
      const uint32_t index_sz = 2 + mag * frames;
 
419
 
 
420
      if (data_sz >= index_sz && data_start[index_sz - 1] == marker) {
 
421
        data_start += index_sz;
 
422
        data_sz -= index_sz;
 
423
        if (data_start < data_end)
 
424
          continue;
 
425
        else
 
426
          break;
 
427
      }
 
428
    }
 
429
 
 
430
    // Use the correct size for this frame, if an index is present.
 
431
    if (frames_this_pts) {
 
432
      uint32_t this_sz = sizes[frame_count];
 
433
 
 
434
      if (data_sz < this_sz) {
 
435
        ctx->base.err_detail = "Invalid frame size in index";
 
436
        return VPX_CODEC_CORRUPT_FRAME;
 
437
      }
 
438
 
 
439
      data_sz = this_sz;
 
440
      frame_count++;
 
441
    }
 
442
 
 
443
    res = decode_one(ctx, &data_start, data_sz, user_priv, deadline);
 
444
    assert(data_start >= data);
 
445
    assert(data_start <= data_end);
 
446
 
 
447
    /* Early exit if there was a decode error */
 
448
    if (res)
 
449
      break;
 
450
 
 
451
    /* Account for suboptimal termination by the encoder. */
 
452
    while (data_start < data_end && *data_start == 0)
 
453
      data_start++;
 
454
 
 
455
    data_sz = data_end - data_start;
 
456
  } while (data_start < data_end);
 
457
  return res;
 
458
}
 
459
 
 
460
static vpx_image_t *vp9_get_frame(vpx_codec_alg_priv_t  *ctx,
 
461
                                  vpx_codec_iter_t      *iter) {
 
462
  vpx_image_t *img = NULL;
 
463
 
 
464
  if (ctx->img_avail) {
 
465
    /* iter acts as a flip flop, so an image is only returned on the first
 
466
     * call to get_frame.
 
467
     */
 
468
    if (!(*iter)) {
 
469
      img = &ctx->img;
 
470
      *iter = img;
 
471
    }
 
472
  }
 
473
  ctx->img_avail = 0;
 
474
 
 
475
  return img;
 
476
}
 
477
 
 
478
static vpx_codec_err_t vp9_xma_get_mmap(const vpx_codec_ctx_t      *ctx,
 
479
                                        vpx_codec_mmap_t           *mmap,
 
480
                                        vpx_codec_iter_t           *iter) {
 
481
  vpx_codec_err_t     res;
 
482
  const mem_req_t  *seg_iter = *iter;
 
483
 
 
484
  /* Get address of next segment request */
 
485
  do {
 
486
    if (!seg_iter)
 
487
      seg_iter = vp9_mem_req_segs;
 
488
    else if (seg_iter->id != VP9_SEG_MAX)
 
489
      seg_iter++;
 
490
 
 
491
    *iter = (vpx_codec_iter_t)seg_iter;
 
492
 
 
493
    if (seg_iter->id != VP9_SEG_MAX) {
 
494
      mmap->id = seg_iter->id;
 
495
      mmap->sz = seg_iter->sz;
 
496
      mmap->align = seg_iter->align;
 
497
      mmap->flags = seg_iter->flags;
 
498
 
 
499
      if (!seg_iter->sz)
 
500
        mmap->sz = seg_iter->calc_sz(ctx->config.dec, ctx->init_flags);
 
501
 
 
502
      res = VPX_CODEC_OK;
 
503
    } else {
 
504
      res = VPX_CODEC_LIST_END;
 
505
    }
 
506
  } while (!mmap->sz && res != VPX_CODEC_LIST_END);
 
507
 
 
508
  return res;
 
509
}
 
510
 
 
511
static vpx_codec_err_t vp9_xma_set_mmap(vpx_codec_ctx_t         *ctx,
 
512
                                        const vpx_codec_mmap_t  *mmap) {
 
513
  vpx_codec_err_t res = VPX_CODEC_MEM_ERROR;
 
514
  int i, done;
 
515
 
 
516
  if (!ctx->priv) {
 
517
    if (mmap->id == VP9_SEG_ALG_PRIV) {
 
518
      if (!ctx->priv) {
 
519
        vp9_init_ctx(ctx, mmap);
 
520
        res = VPX_CODEC_OK;
 
521
      }
 
522
    }
 
523
  }
 
524
 
 
525
  done = 1;
 
526
 
 
527
  if (!res && ctx->priv->alg_priv) {
 
528
    for (i = 0; i < NELEMENTS(ctx->priv->alg_priv->mmaps); i++) {
 
529
      if (ctx->priv->alg_priv->mmaps[i].id == mmap->id)
 
530
        if (!ctx->priv->alg_priv->mmaps[i].base) {
 
531
          ctx->priv->alg_priv->mmaps[i] = *mmap;
 
532
          res = VPX_CODEC_OK;
 
533
        }
 
534
 
 
535
      done &= (ctx->priv->alg_priv->mmaps[i].base != NULL);
 
536
    }
 
537
  }
 
538
 
 
539
  if (done && !res) {
 
540
    vp9_finalize_mmaps(ctx->priv->alg_priv);
 
541
    res = ctx->iface->init(ctx, NULL);
 
542
  }
 
543
 
 
544
  return res;
 
545
}
 
546
 
 
547
static vpx_codec_err_t set_reference(vpx_codec_alg_priv_t *ctx,
 
548
                                     int ctr_id,
 
549
                                     va_list args) {
 
550
  vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *);
 
551
 
 
552
  if (data) {
 
553
    vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data;
 
554
    YV12_BUFFER_CONFIG sd;
 
555
 
 
556
    image2yuvconfig(&frame->img, &sd);
 
557
 
 
558
    return vp9_set_reference_dec(ctx->pbi,
 
559
                                 (VP9_REFFRAME)frame->frame_type, &sd);
 
560
  } else {
 
561
    return VPX_CODEC_INVALID_PARAM;
 
562
  }
 
563
}
 
564
 
 
565
static vpx_codec_err_t copy_reference(vpx_codec_alg_priv_t *ctx,
 
566
                                      int ctr_id,
 
567
                                      va_list args) {
 
568
  vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *);
 
569
 
 
570
  if (data) {
 
571
    vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data;
 
572
    YV12_BUFFER_CONFIG sd;
 
573
 
 
574
    image2yuvconfig(&frame->img, &sd);
 
575
 
 
576
    return vp9_copy_reference_dec(ctx->pbi,
 
577
                                  (VP9_REFFRAME)frame->frame_type, &sd);
 
578
  } else {
 
579
    return VPX_CODEC_INVALID_PARAM;
 
580
  }
 
581
}
 
582
 
 
583
static vpx_codec_err_t get_reference(vpx_codec_alg_priv_t *ctx,
 
584
                                     int ctr_id,
 
585
                                     va_list args) {
 
586
  vp9_ref_frame_t *data = va_arg(args, vp9_ref_frame_t *);
 
587
 
 
588
  if (data) {
 
589
    YV12_BUFFER_CONFIG* fb;
 
590
 
 
591
    vp9_get_reference_dec(ctx->pbi, data->idx, &fb);
 
592
    yuvconfig2image(&data->img, fb, NULL);
 
593
    return VPX_CODEC_OK;
 
594
  } else {
 
595
    return VPX_CODEC_INVALID_PARAM;
 
596
  }
 
597
}
 
598
 
 
599
static vpx_codec_err_t set_postproc(vpx_codec_alg_priv_t *ctx,
 
600
                                    int ctr_id,
 
601
                                    va_list args) {
 
602
#if CONFIG_VP9_POSTPROC
 
603
  vp8_postproc_cfg_t *data = va_arg(args, vp8_postproc_cfg_t *);
 
604
 
 
605
  if (data) {
 
606
    ctx->postproc_cfg_set = 1;
 
607
    ctx->postproc_cfg = *((vp8_postproc_cfg_t *)data);
 
608
    return VPX_CODEC_OK;
 
609
  } else {
 
610
    return VPX_CODEC_INVALID_PARAM;
 
611
  }
 
612
#else
 
613
  return VPX_CODEC_INCAPABLE;
 
614
#endif
 
615
}
 
616
 
 
617
static vpx_codec_err_t set_dbg_options(vpx_codec_alg_priv_t *ctx,
 
618
                                       int ctrl_id,
 
619
                                       va_list args) {
 
620
#if CONFIG_POSTPROC_VISUALIZER && CONFIG_POSTPROC
 
621
  int data = va_arg(args, int);
 
622
 
 
623
#define MAP(id, var) case id: var = data; break;
 
624
 
 
625
  switch (ctrl_id) {
 
626
      MAP(VP8_SET_DBG_COLOR_REF_FRAME,   ctx->dbg_color_ref_frame_flag);
 
627
      MAP(VP8_SET_DBG_COLOR_MB_MODES,    ctx->dbg_color_mb_modes_flag);
 
628
      MAP(VP8_SET_DBG_COLOR_B_MODES,     ctx->dbg_color_b_modes_flag);
 
629
      MAP(VP8_SET_DBG_DISPLAY_MV,        ctx->dbg_display_mv_flag);
 
630
  }
 
631
 
 
632
  return VPX_CODEC_OK;
 
633
#else
 
634
  return VPX_CODEC_INCAPABLE;
 
635
#endif
 
636
}
 
637
 
 
638
static vpx_codec_err_t get_last_ref_updates(vpx_codec_alg_priv_t *ctx,
 
639
                                            int ctrl_id,
 
640
                                            va_list args) {
 
641
  int *update_info = va_arg(args, int *);
 
642
  VP9D_COMP *pbi = (VP9D_COMP *)ctx->pbi;
 
643
 
 
644
  if (update_info) {
 
645
    *update_info = pbi->refresh_frame_flags;
 
646
 
 
647
    return VPX_CODEC_OK;
 
648
  } else {
 
649
    return VPX_CODEC_INVALID_PARAM;
 
650
  }
 
651
}
 
652
 
 
653
 
 
654
static vpx_codec_err_t get_frame_corrupted(vpx_codec_alg_priv_t *ctx,
 
655
                                           int ctrl_id,
 
656
                                           va_list args) {
 
657
  int *corrupted = va_arg(args, int *);
 
658
 
 
659
  if (corrupted) {
 
660
    VP9D_COMP *pbi = (VP9D_COMP *)ctx->pbi;
 
661
    if (pbi)
 
662
      *corrupted = pbi->common.frame_to_show->corrupted;
 
663
    else
 
664
      return VPX_CODEC_ERROR;
 
665
    return VPX_CODEC_OK;
 
666
  } else {
 
667
    return VPX_CODEC_INVALID_PARAM;
 
668
  }
 
669
}
 
670
 
 
671
static vpx_codec_err_t set_invert_tile_order(vpx_codec_alg_priv_t *ctx,
 
672
                                             int ctr_id,
 
673
                                             va_list args) {
 
674
  ctx->invert_tile_order = va_arg(args, int);
 
675
  return VPX_CODEC_OK;
 
676
}
 
677
 
 
678
static vpx_codec_ctrl_fn_map_t ctf_maps[] = {
 
679
  {VP8_SET_REFERENCE,             set_reference},
 
680
  {VP8_COPY_REFERENCE,            copy_reference},
 
681
  {VP8_SET_POSTPROC,              set_postproc},
 
682
  {VP8_SET_DBG_COLOR_REF_FRAME,   set_dbg_options},
 
683
  {VP8_SET_DBG_COLOR_MB_MODES,    set_dbg_options},
 
684
  {VP8_SET_DBG_COLOR_B_MODES,     set_dbg_options},
 
685
  {VP8_SET_DBG_DISPLAY_MV,        set_dbg_options},
 
686
  {VP8D_GET_LAST_REF_UPDATES,     get_last_ref_updates},
 
687
  {VP8D_GET_FRAME_CORRUPTED,      get_frame_corrupted},
 
688
  {VP9_GET_REFERENCE,             get_reference},
 
689
  {VP9_INVERT_TILE_DECODE_ORDER,  set_invert_tile_order},
 
690
  { -1, NULL},
 
691
};
 
692
 
 
693
 
 
694
#ifndef VERSION_STRING
 
695
#define VERSION_STRING
 
696
#endif
 
697
CODEC_INTERFACE(vpx_codec_vp9_dx) = {
 
698
  "WebM Project VP9 Decoder" VERSION_STRING,
 
699
  VPX_CODEC_INTERNAL_ABI_VERSION,
 
700
  VPX_CODEC_CAP_DECODER | VP9_CAP_POSTPROC,
 
701
  /* vpx_codec_caps_t          caps; */
 
702
  vp9_init,         /* vpx_codec_init_fn_t       init; */
 
703
  vp9_destroy,      /* vpx_codec_destroy_fn_t    destroy; */
 
704
  ctf_maps,         /* vpx_codec_ctrl_fn_map_t  *ctrl_maps; */
 
705
  vp9_xma_get_mmap, /* vpx_codec_get_mmap_fn_t   get_mmap; */
 
706
  vp9_xma_set_mmap, /* vpx_codec_set_mmap_fn_t   set_mmap; */
 
707
  { // NOLINT
 
708
    vp9_peek_si,      /* vpx_codec_peek_si_fn_t    peek_si; */
 
709
    vp9_get_si,       /* vpx_codec_get_si_fn_t     get_si; */
 
710
    vp9_decode,       /* vpx_codec_decode_fn_t     decode; */
 
711
    vp9_get_frame,    /* vpx_codec_frame_get_fn_t  frame_get; */
 
712
  },
 
713
  { // NOLINT
 
714
    /* encoder functions */
 
715
    NOT_IMPLEMENTED,
 
716
    NOT_IMPLEMENTED,
 
717
    NOT_IMPLEMENTED,
 
718
    NOT_IMPLEMENTED,
 
719
    NOT_IMPLEMENTED,
 
720
    NOT_IMPLEMENTED
 
721
  }
 
722
};