Thu, 15 Jan 2015 15:59:08 +0100
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 <stdarg.h> |
michael@0 | 17 | #include <stdlib.h> |
michael@0 | 18 | #include "vpx/vpx_integer.h" |
michael@0 | 19 | #include "vpx/internal/vpx_codec_internal.h" |
michael@0 | 20 | #include "vpx_version.h" |
michael@0 | 21 | |
michael@0 | 22 | #define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var) |
michael@0 | 23 | |
michael@0 | 24 | int vpx_codec_version(void) { |
michael@0 | 25 | return VERSION_PACKED; |
michael@0 | 26 | } |
michael@0 | 27 | |
michael@0 | 28 | |
michael@0 | 29 | const char *vpx_codec_version_str(void) { |
michael@0 | 30 | return VERSION_STRING_NOSP; |
michael@0 | 31 | } |
michael@0 | 32 | |
michael@0 | 33 | |
michael@0 | 34 | const char *vpx_codec_version_extra_str(void) { |
michael@0 | 35 | return VERSION_EXTRA; |
michael@0 | 36 | } |
michael@0 | 37 | |
michael@0 | 38 | |
michael@0 | 39 | const char *vpx_codec_iface_name(vpx_codec_iface_t *iface) { |
michael@0 | 40 | return iface ? iface->name : "<invalid interface>"; |
michael@0 | 41 | } |
michael@0 | 42 | |
michael@0 | 43 | const char *vpx_codec_err_to_string(vpx_codec_err_t err) { |
michael@0 | 44 | switch (err) { |
michael@0 | 45 | case VPX_CODEC_OK: |
michael@0 | 46 | return "Success"; |
michael@0 | 47 | case VPX_CODEC_ERROR: |
michael@0 | 48 | return "Unspecified internal error"; |
michael@0 | 49 | case VPX_CODEC_MEM_ERROR: |
michael@0 | 50 | return "Memory allocation error"; |
michael@0 | 51 | case VPX_CODEC_ABI_MISMATCH: |
michael@0 | 52 | return "ABI version mismatch"; |
michael@0 | 53 | case VPX_CODEC_INCAPABLE: |
michael@0 | 54 | return "Codec does not implement requested capability"; |
michael@0 | 55 | case VPX_CODEC_UNSUP_BITSTREAM: |
michael@0 | 56 | return "Bitstream not supported by this decoder"; |
michael@0 | 57 | case VPX_CODEC_UNSUP_FEATURE: |
michael@0 | 58 | return "Bitstream required feature not supported by this decoder"; |
michael@0 | 59 | case VPX_CODEC_CORRUPT_FRAME: |
michael@0 | 60 | return "Corrupt frame detected"; |
michael@0 | 61 | case VPX_CODEC_INVALID_PARAM: |
michael@0 | 62 | return "Invalid parameter"; |
michael@0 | 63 | case VPX_CODEC_LIST_END: |
michael@0 | 64 | return "End of iterated list"; |
michael@0 | 65 | } |
michael@0 | 66 | |
michael@0 | 67 | return "Unrecognized error code"; |
michael@0 | 68 | } |
michael@0 | 69 | |
michael@0 | 70 | const char *vpx_codec_error(vpx_codec_ctx_t *ctx) { |
michael@0 | 71 | return (ctx) ? vpx_codec_err_to_string(ctx->err) |
michael@0 | 72 | : vpx_codec_err_to_string(VPX_CODEC_INVALID_PARAM); |
michael@0 | 73 | } |
michael@0 | 74 | |
michael@0 | 75 | const char *vpx_codec_error_detail(vpx_codec_ctx_t *ctx) { |
michael@0 | 76 | if (ctx && ctx->err) |
michael@0 | 77 | return ctx->priv ? ctx->priv->err_detail : ctx->err_detail; |
michael@0 | 78 | |
michael@0 | 79 | return NULL; |
michael@0 | 80 | } |
michael@0 | 81 | |
michael@0 | 82 | |
michael@0 | 83 | vpx_codec_err_t vpx_codec_destroy(vpx_codec_ctx_t *ctx) { |
michael@0 | 84 | vpx_codec_err_t res; |
michael@0 | 85 | |
michael@0 | 86 | if (!ctx) |
michael@0 | 87 | res = VPX_CODEC_INVALID_PARAM; |
michael@0 | 88 | else if (!ctx->iface || !ctx->priv) |
michael@0 | 89 | res = VPX_CODEC_ERROR; |
michael@0 | 90 | else { |
michael@0 | 91 | if (ctx->priv->alg_priv) |
michael@0 | 92 | ctx->iface->destroy(ctx->priv->alg_priv); |
michael@0 | 93 | |
michael@0 | 94 | ctx->iface = NULL; |
michael@0 | 95 | ctx->name = NULL; |
michael@0 | 96 | ctx->priv = NULL; |
michael@0 | 97 | res = VPX_CODEC_OK; |
michael@0 | 98 | } |
michael@0 | 99 | |
michael@0 | 100 | return SAVE_STATUS(ctx, res); |
michael@0 | 101 | } |
michael@0 | 102 | |
michael@0 | 103 | |
michael@0 | 104 | vpx_codec_caps_t vpx_codec_get_caps(vpx_codec_iface_t *iface) { |
michael@0 | 105 | return (iface) ? iface->caps : 0; |
michael@0 | 106 | } |
michael@0 | 107 | |
michael@0 | 108 | |
michael@0 | 109 | vpx_codec_err_t vpx_codec_control_(vpx_codec_ctx_t *ctx, |
michael@0 | 110 | int ctrl_id, |
michael@0 | 111 | ...) { |
michael@0 | 112 | vpx_codec_err_t res; |
michael@0 | 113 | |
michael@0 | 114 | if (!ctx || !ctrl_id) |
michael@0 | 115 | res = VPX_CODEC_INVALID_PARAM; |
michael@0 | 116 | else if (!ctx->iface || !ctx->priv || !ctx->iface->ctrl_maps) |
michael@0 | 117 | res = VPX_CODEC_ERROR; |
michael@0 | 118 | else { |
michael@0 | 119 | vpx_codec_ctrl_fn_map_t *entry; |
michael@0 | 120 | |
michael@0 | 121 | res = VPX_CODEC_ERROR; |
michael@0 | 122 | |
michael@0 | 123 | for (entry = ctx->iface->ctrl_maps; entry && entry->fn; entry++) { |
michael@0 | 124 | if (!entry->ctrl_id || entry->ctrl_id == ctrl_id) { |
michael@0 | 125 | va_list ap; |
michael@0 | 126 | |
michael@0 | 127 | va_start(ap, ctrl_id); |
michael@0 | 128 | res = entry->fn(ctx->priv->alg_priv, ctrl_id, ap); |
michael@0 | 129 | va_end(ap); |
michael@0 | 130 | break; |
michael@0 | 131 | } |
michael@0 | 132 | } |
michael@0 | 133 | } |
michael@0 | 134 | |
michael@0 | 135 | return SAVE_STATUS(ctx, res); |
michael@0 | 136 | } |
michael@0 | 137 | |
michael@0 | 138 | //------------------------------------------------------------------------------ |
michael@0 | 139 | // mmap interface |
michael@0 | 140 | |
michael@0 | 141 | vpx_codec_err_t vpx_mmap_alloc(vpx_codec_mmap_t *mmap) { |
michael@0 | 142 | unsigned int align = mmap->align ? mmap->align - 1 : 0; |
michael@0 | 143 | |
michael@0 | 144 | if (mmap->flags & VPX_CODEC_MEM_ZERO) |
michael@0 | 145 | mmap->priv = calloc(1, mmap->sz + align); |
michael@0 | 146 | else |
michael@0 | 147 | mmap->priv = malloc(mmap->sz + align); |
michael@0 | 148 | |
michael@0 | 149 | if (mmap->priv == NULL) return VPX_CODEC_MEM_ERROR; |
michael@0 | 150 | mmap->base = (void *)((((uintptr_t)mmap->priv) + align) & ~(uintptr_t)align); |
michael@0 | 151 | mmap->dtor = vpx_mmap_dtor; |
michael@0 | 152 | return VPX_CODEC_OK; |
michael@0 | 153 | } |
michael@0 | 154 | |
michael@0 | 155 | void vpx_mmap_dtor(vpx_codec_mmap_t *mmap) { |
michael@0 | 156 | free(mmap->priv); |
michael@0 | 157 | } |
michael@0 | 158 | |
michael@0 | 159 | vpx_codec_err_t vpx_validate_mmaps(const vpx_codec_stream_info_t *si, |
michael@0 | 160 | const vpx_codec_mmap_t *mmaps, |
michael@0 | 161 | const mem_req_t *mem_reqs, int nreqs, |
michael@0 | 162 | vpx_codec_flags_t init_flags) { |
michael@0 | 163 | int i; |
michael@0 | 164 | |
michael@0 | 165 | for (i = 0; i < nreqs - 1; ++i) { |
michael@0 | 166 | /* Ensure the segment has been allocated */ |
michael@0 | 167 | if (mmaps[i].base == NULL) { |
michael@0 | 168 | return VPX_CODEC_MEM_ERROR; |
michael@0 | 169 | } |
michael@0 | 170 | |
michael@0 | 171 | /* Verify variable size segment is big enough for the current si. */ |
michael@0 | 172 | if (mem_reqs[i].calc_sz != NULL) { |
michael@0 | 173 | vpx_codec_dec_cfg_t cfg; |
michael@0 | 174 | |
michael@0 | 175 | cfg.w = si->w; |
michael@0 | 176 | cfg.h = si->h; |
michael@0 | 177 | |
michael@0 | 178 | if (mmaps[i].sz < mem_reqs[i].calc_sz(&cfg, init_flags)) { |
michael@0 | 179 | return VPX_CODEC_MEM_ERROR; |
michael@0 | 180 | } |
michael@0 | 181 | } |
michael@0 | 182 | } |
michael@0 | 183 | return VPX_CODEC_OK; |
michael@0 | 184 | } |