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/* This is a simple program showing how to initialize the decoder in XMA mode */ 13#include <stdio.h> 14#include <stdlib.h> 15#include <stdarg.h> 16#include <string.h> 17#define VPX_CODEC_DISABLE_COMPAT 1 18#include "vpx_config.h" 19#include "vpx/vpx_decoder.h" 20#include "vpx/vpx_integer.h" 21#if CONFIG_VP8_DECODER 22#include "vpx/vp8dx.h" 23#endif 24 25static char *exec_name; 26static int verbose = 0; 27 28static const struct 29{ 30 const char *name; 31 const vpx_codec_iface_t *iface; 32} ifaces[] = 33{ 34#if CONFIG_VP8_DECODER 35 {"vp8", &vpx_codec_vp8_dx_algo}, 36#endif 37}; 38 39static void usage_exit(void) 40{ 41 int i; 42 43 printf("Usage: %s <options>\n\n" 44 "Options:\n" 45 "\t--codec <name>\tCodec to use (default=%s)\n" 46 "\t-h <height>\tHeight of the simulated video frame, in pixels\n" 47 "\t-w <width> \tWidth of the simulated video frame, in pixels\n" 48 "\t-v \tVerbose mode (show individual segment sizes)\n" 49 "\t--help \tShow this message\n" 50 "\n" 51 "Included decoders:\n" 52 "\n", 53 exec_name, 54 ifaces[0].name); 55 56 for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++) 57 printf(" %-6s - %s\n", 58 ifaces[i].name, 59 vpx_codec_iface_name(ifaces[i].iface)); 60 61 exit(EXIT_FAILURE); 62} 63 64static void usage_error(const char *fmt, ...) 65{ 66 va_list ap; 67 va_start(ap, fmt); 68 vprintf(fmt, ap); 69 printf("\n"); 70 usage_exit(); 71} 72 73void my_mem_dtor(vpx_codec_mmap_t *mmap) 74{ 75 if (verbose) 76 printf("freeing segment %d\n", mmap->id); 77 78 free(mmap->priv); 79} 80 81int main(int argc, char **argv) 82{ 83 vpx_codec_ctx_t decoder; 84 vpx_codec_iface_t *iface = ifaces[0].iface; 85 vpx_codec_iter_t iter; 86 vpx_codec_dec_cfg_t cfg; 87 vpx_codec_err_t res = VPX_CODEC_OK; 88 unsigned int alloc_sz = 0; 89 unsigned int w = 352; 90 unsigned int h = 288; 91 int i; 92 93 exec_name = argv[0]; 94 95 for (i = 1; i < argc; i++) 96 { 97 if (!strcmp(argv[i], "--codec")) 98 { 99 if (i + 1 < argc) 100 { 101 int j, k = -1; 102 103 i++; 104 105 for (j = 0; j < sizeof(ifaces) / sizeof(ifaces[0]); j++) 106 if (!strcmp(ifaces[j].name, argv[i])) 107 k = j; 108 109 if (k >= 0) 110 iface = ifaces[k].iface; 111 else 112 usage_error("Error: Unrecognized argument (%s) to --codec\n", 113 argv[i]); 114 } 115 else 116 usage_error("Error: Option --codec requires argument.\n"); 117 } 118 else if (!strcmp(argv[i], "-v")) 119 verbose = 1; 120 else if (!strcmp(argv[i], "-h")) 121 if (i + 1 < argc) 122 { 123 h = atoi(argv[++i]); 124 } 125 else 126 usage_error("Error: Option -h requires argument.\n"); 127 else if (!strcmp(argv[i], "-w")) 128 if (i + 1 < argc) 129 { 130 w = atoi(argv[++i]); 131 } 132 else 133 usage_error("Error: Option -w requires argument.\n"); 134 else if (!strcmp(argv[i], "--help")) 135 usage_exit(); 136 else 137 usage_error("Error: Unrecognized option %s\n\n", argv[i]); 138 } 139 140 if (argc == 1) 141 printf("Using built-in defaults. For options, rerun with --help\n\n"); 142 143 /* XMA mode is not supported on all decoders! */ 144 if (!(vpx_codec_get_caps(iface) & VPX_CODEC_CAP_XMA)) 145 { 146 printf("%s does not support XMA mode!\n", vpx_codec_iface_name(iface)); 147 return EXIT_FAILURE; 148 } 149 150 /* The codec knows how much memory to allocate based on the size of the 151 * encoded frames. This data can be parsed from the bitstream with 152 * vpx_codec_peek_stream_info() if a bitstream is available. Otherwise, 153 * a fixed size can be used that will be the upper limit on the frame 154 * size the decoder can decode. 155 */ 156 cfg.w = w; 157 cfg.h = h; 158 159 /* Initialize the decoder in XMA mode. */ 160 if (vpx_codec_dec_init(&decoder, iface, &cfg, VPX_CODEC_USE_XMA)) 161 { 162 printf("Failed to initialize decoder in XMA mode: %s\n", vpx_codec_error(&decoder)); 163 return EXIT_FAILURE; 164 } 165 166 /* Iterate through the list of memory maps, allocating them with the 167 * requested alignment. 168 */ 169 iter = NULL; 170 171 do 172 { 173 vpx_codec_mmap_t mmap; 174 unsigned int align; 175 176 res = vpx_codec_get_mem_map(&decoder, &mmap, &iter); 177 align = mmap.align ? mmap.align - 1 : 0; 178 179 if (!res) 180 { 181 if (verbose) 182 printf("Allocating segment %u, size %lu, align %u %s\n", 183 mmap.id, mmap.sz, mmap.align, 184 mmap.flags & VPX_CODEC_MEM_ZERO ? "(ZEROED)" : ""); 185 186 if (mmap.flags & VPX_CODEC_MEM_ZERO) 187 mmap.priv = calloc(1, mmap.sz + align); 188 else 189 mmap.priv = malloc(mmap.sz + align); 190 191 mmap.base = (void *)((((uintptr_t)mmap.priv) + align) & ~(uintptr_t)align); 192 mmap.dtor = my_mem_dtor; 193 alloc_sz += mmap.sz + align; 194 195 if (vpx_codec_set_mem_map(&decoder, &mmap, 1)) 196 { 197 printf("Failed to set mmap: %s\n", vpx_codec_error(&decoder)); 198 return EXIT_FAILURE; 199 } 200 } 201 else if (res != VPX_CODEC_LIST_END) 202 { 203 printf("Failed to get mmap: %s\n", vpx_codec_error(&decoder)); 204 return EXIT_FAILURE; 205 } 206 } 207 while (res != VPX_CODEC_LIST_END); 208 209 printf("%s\n %d bytes external memory required for %dx%d.\n", 210 decoder.name, alloc_sz, cfg.w, cfg.h); 211 vpx_codec_destroy(&decoder); 212 return EXIT_SUCCESS; 213 214} 215