media/libvpx/vpx/src/vpx_decoder.c

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /*
michael@0 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license
michael@0 5 * that can be found in the LICENSE file in the root of the source
michael@0 6 * tree. An additional intellectual property rights grant can be found
michael@0 7 * in the file PATENTS. All contributing project authors may
michael@0 8 * be found in the AUTHORS file in the root of the source tree.
michael@0 9 */
michael@0 10
michael@0 11
michael@0 12 /*!\file
michael@0 13 * \brief Provides the high level interface to wrap decoder algorithms.
michael@0 14 *
michael@0 15 */
michael@0 16 #include <string.h>
michael@0 17 #include "vpx/internal/vpx_codec_internal.h"
michael@0 18
michael@0 19 #define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var)
michael@0 20
michael@0 21 vpx_codec_err_t vpx_codec_dec_init_ver(vpx_codec_ctx_t *ctx,
michael@0 22 vpx_codec_iface_t *iface,
michael@0 23 vpx_codec_dec_cfg_t *cfg,
michael@0 24 vpx_codec_flags_t flags,
michael@0 25 int ver) {
michael@0 26 vpx_codec_err_t res;
michael@0 27
michael@0 28 if (ver != VPX_DECODER_ABI_VERSION)
michael@0 29 res = VPX_CODEC_ABI_MISMATCH;
michael@0 30 else if (!ctx || !iface)
michael@0 31 res = VPX_CODEC_INVALID_PARAM;
michael@0 32 else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION)
michael@0 33 res = VPX_CODEC_ABI_MISMATCH;
michael@0 34 else if ((flags & VPX_CODEC_USE_XMA) && !(iface->caps & VPX_CODEC_CAP_XMA))
michael@0 35 res = VPX_CODEC_INCAPABLE;
michael@0 36 else if ((flags & VPX_CODEC_USE_POSTPROC) && !(iface->caps & VPX_CODEC_CAP_POSTPROC))
michael@0 37 res = VPX_CODEC_INCAPABLE;
michael@0 38 else if ((flags & VPX_CODEC_USE_ERROR_CONCEALMENT) &&
michael@0 39 !(iface->caps & VPX_CODEC_CAP_ERROR_CONCEALMENT))
michael@0 40 res = VPX_CODEC_INCAPABLE;
michael@0 41 else if ((flags & VPX_CODEC_USE_INPUT_FRAGMENTS) &&
michael@0 42 !(iface->caps & VPX_CODEC_CAP_INPUT_FRAGMENTS))
michael@0 43 res = VPX_CODEC_INCAPABLE;
michael@0 44 else if (!(iface->caps & VPX_CODEC_CAP_DECODER))
michael@0 45 res = VPX_CODEC_INCAPABLE;
michael@0 46 else {
michael@0 47 memset(ctx, 0, sizeof(*ctx));
michael@0 48 ctx->iface = iface;
michael@0 49 ctx->name = iface->name;
michael@0 50 ctx->priv = NULL;
michael@0 51 ctx->init_flags = flags;
michael@0 52 ctx->config.dec = cfg;
michael@0 53 res = VPX_CODEC_OK;
michael@0 54
michael@0 55 if (!(flags & VPX_CODEC_USE_XMA)) {
michael@0 56 res = ctx->iface->init(ctx, NULL);
michael@0 57
michael@0 58 if (res) {
michael@0 59 ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
michael@0 60 vpx_codec_destroy(ctx);
michael@0 61 }
michael@0 62
michael@0 63 if (ctx->priv)
michael@0 64 ctx->priv->iface = ctx->iface;
michael@0 65 }
michael@0 66 }
michael@0 67
michael@0 68 return SAVE_STATUS(ctx, res);
michael@0 69 }
michael@0 70
michael@0 71
michael@0 72 vpx_codec_err_t vpx_codec_peek_stream_info(vpx_codec_iface_t *iface,
michael@0 73 const uint8_t *data,
michael@0 74 unsigned int data_sz,
michael@0 75 vpx_codec_stream_info_t *si) {
michael@0 76 vpx_codec_err_t res;
michael@0 77
michael@0 78 if (!iface || !data || !data_sz || !si
michael@0 79 || si->sz < sizeof(vpx_codec_stream_info_t))
michael@0 80 res = VPX_CODEC_INVALID_PARAM;
michael@0 81 else {
michael@0 82 /* Set default/unknown values */
michael@0 83 si->w = 0;
michael@0 84 si->h = 0;
michael@0 85
michael@0 86 res = iface->dec.peek_si(data, data_sz, si);
michael@0 87 }
michael@0 88
michael@0 89 return res;
michael@0 90 }
michael@0 91
michael@0 92
michael@0 93 vpx_codec_err_t vpx_codec_get_stream_info(vpx_codec_ctx_t *ctx,
michael@0 94 vpx_codec_stream_info_t *si) {
michael@0 95 vpx_codec_err_t res;
michael@0 96
michael@0 97 if (!ctx || !si || si->sz < sizeof(vpx_codec_stream_info_t))
michael@0 98 res = VPX_CODEC_INVALID_PARAM;
michael@0 99 else if (!ctx->iface || !ctx->priv)
michael@0 100 res = VPX_CODEC_ERROR;
michael@0 101 else {
michael@0 102 /* Set default/unknown values */
michael@0 103 si->w = 0;
michael@0 104 si->h = 0;
michael@0 105
michael@0 106 res = ctx->iface->dec.get_si(ctx->priv->alg_priv, si);
michael@0 107 }
michael@0 108
michael@0 109 return SAVE_STATUS(ctx, res);
michael@0 110 }
michael@0 111
michael@0 112
michael@0 113 vpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t *ctx,
michael@0 114 const uint8_t *data,
michael@0 115 unsigned int data_sz,
michael@0 116 void *user_priv,
michael@0 117 long deadline) {
michael@0 118 vpx_codec_err_t res;
michael@0 119
michael@0 120 /* Sanity checks */
michael@0 121 /* NULL data ptr allowed if data_sz is 0 too */
michael@0 122 if (!ctx || (!data && data_sz))
michael@0 123 res = VPX_CODEC_INVALID_PARAM;
michael@0 124 else if (!ctx->iface || !ctx->priv)
michael@0 125 res = VPX_CODEC_ERROR;
michael@0 126 else {
michael@0 127 res = ctx->iface->dec.decode(ctx->priv->alg_priv, data, data_sz,
michael@0 128 user_priv, deadline);
michael@0 129 }
michael@0 130
michael@0 131 return SAVE_STATUS(ctx, res);
michael@0 132 }
michael@0 133
michael@0 134 vpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t *ctx,
michael@0 135 vpx_codec_iter_t *iter) {
michael@0 136 vpx_image_t *img;
michael@0 137
michael@0 138 if (!ctx || !iter || !ctx->iface || !ctx->priv)
michael@0 139 img = NULL;
michael@0 140 else
michael@0 141 img = ctx->iface->dec.get_frame(ctx->priv->alg_priv, iter);
michael@0 142
michael@0 143 return img;
michael@0 144 }
michael@0 145
michael@0 146
michael@0 147 vpx_codec_err_t vpx_codec_register_put_frame_cb(vpx_codec_ctx_t *ctx,
michael@0 148 vpx_codec_put_frame_cb_fn_t cb,
michael@0 149 void *user_priv) {
michael@0 150 vpx_codec_err_t res;
michael@0 151
michael@0 152 if (!ctx || !cb)
michael@0 153 res = VPX_CODEC_INVALID_PARAM;
michael@0 154 else if (!ctx->iface || !ctx->priv
michael@0 155 || !(ctx->iface->caps & VPX_CODEC_CAP_PUT_FRAME))
michael@0 156 res = VPX_CODEC_ERROR;
michael@0 157 else {
michael@0 158 ctx->priv->dec.put_frame_cb.u.put_frame = cb;
michael@0 159 ctx->priv->dec.put_frame_cb.user_priv = user_priv;
michael@0 160 res = VPX_CODEC_OK;
michael@0 161 }
michael@0 162
michael@0 163 return SAVE_STATUS(ctx, res);
michael@0 164 }
michael@0 165
michael@0 166
michael@0 167 vpx_codec_err_t vpx_codec_register_put_slice_cb(vpx_codec_ctx_t *ctx,
michael@0 168 vpx_codec_put_slice_cb_fn_t cb,
michael@0 169 void *user_priv) {
michael@0 170 vpx_codec_err_t res;
michael@0 171
michael@0 172 if (!ctx || !cb)
michael@0 173 res = VPX_CODEC_INVALID_PARAM;
michael@0 174 else if (!ctx->iface || !ctx->priv
michael@0 175 || !(ctx->iface->caps & VPX_CODEC_CAP_PUT_FRAME))
michael@0 176 res = VPX_CODEC_ERROR;
michael@0 177 else {
michael@0 178 ctx->priv->dec.put_slice_cb.u.put_slice = cb;
michael@0 179 ctx->priv->dec.put_slice_cb.user_priv = user_priv;
michael@0 180 res = VPX_CODEC_OK;
michael@0 181 }
michael@0 182
michael@0 183 return SAVE_STATUS(ctx, res);
michael@0 184 }
michael@0 185
michael@0 186
michael@0 187 vpx_codec_err_t vpx_codec_get_mem_map(vpx_codec_ctx_t *ctx,
michael@0 188 vpx_codec_mmap_t *mmap,
michael@0 189 vpx_codec_iter_t *iter) {
michael@0 190 vpx_codec_err_t res = VPX_CODEC_OK;
michael@0 191
michael@0 192 if (!ctx || !mmap || !iter || !ctx->iface)
michael@0 193 res = VPX_CODEC_INVALID_PARAM;
michael@0 194 else if (!(ctx->iface->caps & VPX_CODEC_CAP_XMA))
michael@0 195 res = VPX_CODEC_ERROR;
michael@0 196 else
michael@0 197 res = ctx->iface->get_mmap(ctx, mmap, iter);
michael@0 198
michael@0 199 return SAVE_STATUS(ctx, res);
michael@0 200 }
michael@0 201
michael@0 202
michael@0 203 vpx_codec_err_t vpx_codec_set_mem_map(vpx_codec_ctx_t *ctx,
michael@0 204 vpx_codec_mmap_t *mmap,
michael@0 205 unsigned int num_maps) {
michael@0 206 vpx_codec_err_t res = VPX_CODEC_MEM_ERROR;
michael@0 207
michael@0 208 if (!ctx || !mmap || !ctx->iface)
michael@0 209 res = VPX_CODEC_INVALID_PARAM;
michael@0 210 else if (!(ctx->iface->caps & VPX_CODEC_CAP_XMA))
michael@0 211 res = VPX_CODEC_ERROR;
michael@0 212 else {
michael@0 213 unsigned int i;
michael@0 214
michael@0 215 for (i = 0; i < num_maps; i++, mmap++) {
michael@0 216 if (!mmap->base)
michael@0 217 break;
michael@0 218
michael@0 219 /* Everything look ok, set the mmap in the decoder */
michael@0 220 res = ctx->iface->set_mmap(ctx, mmap);
michael@0 221
michael@0 222 if (res)
michael@0 223 break;
michael@0 224 }
michael@0 225 }
michael@0 226
michael@0 227 return SAVE_STATUS(ctx, res);
michael@0 228 }

mercurial