1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* 2233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3233d2500723e5594f3e7c70896ffeeef32b9c950ywan * 4233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Use of this source code is governed by a BSD-style license 5233d2500723e5594f3e7c70896ffeeef32b9c950ywan * that can be found in the LICENSE file in the root of the source 6233d2500723e5594f3e7c70896ffeeef32b9c950ywan * tree. An additional intellectual property rights grant can be found 7233d2500723e5594f3e7c70896ffeeef32b9c950ywan * in the file PATENTS. All contributing project authors may 8233d2500723e5594f3e7c70896ffeeef32b9c950ywan * be found in the AUTHORS file in the root of the source tree. 9233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 10233d2500723e5594f3e7c70896ffeeef32b9c950ywan 11233d2500723e5594f3e7c70896ffeeef32b9c950ywan 12233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* This is a simple program showing how to initialize the decoder in XMA mode */ 13233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <stdio.h> 14233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <stdlib.h> 15233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <stdarg.h> 16233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <string.h> 17233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define VPX_CODEC_DISABLE_COMPAT 1 18233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx_config.h" 19233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx/vpx_decoder.h" 20233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx/vpx_integer.h" 21233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if CONFIG_VP9_DECODER 22233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "vpx/vp8dx.h" 23233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 24233d2500723e5594f3e7c70896ffeeef32b9c950ywan 25233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic char *exec_name; 26233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int verbose = 0; 27233d2500723e5594f3e7c70896ffeeef32b9c950ywan 28233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic const struct { 29233d2500723e5594f3e7c70896ffeeef32b9c950ywan const char *name; 30233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_iface_t *iface; 31233d2500723e5594f3e7c70896ffeeef32b9c950ywan} ifaces[] = { 32233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if CONFIG_VP9_DECODER 33233d2500723e5594f3e7c70896ffeeef32b9c950ywan {"vp9", &vpx_codec_vp8_dx_algo}, 34233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif 35233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 36233d2500723e5594f3e7c70896ffeeef32b9c950ywan 37233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void usage_exit(void) { 38233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 39233d2500723e5594f3e7c70896ffeeef32b9c950ywan 40233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("Usage: %s <options>\n\n" 41233d2500723e5594f3e7c70896ffeeef32b9c950ywan "Options:\n" 42233d2500723e5594f3e7c70896ffeeef32b9c950ywan "\t--codec <name>\tCodec to use (default=%s)\n" 43233d2500723e5594f3e7c70896ffeeef32b9c950ywan "\t-h <height>\tHeight of the simulated video frame, in pixels\n" 44233d2500723e5594f3e7c70896ffeeef32b9c950ywan "\t-w <width> \tWidth of the simulated video frame, in pixels\n" 45233d2500723e5594f3e7c70896ffeeef32b9c950ywan "\t-v \tVerbose mode (show individual segment sizes)\n" 46233d2500723e5594f3e7c70896ffeeef32b9c950ywan "\t--help \tShow this message\n" 47233d2500723e5594f3e7c70896ffeeef32b9c950ywan "\n" 48233d2500723e5594f3e7c70896ffeeef32b9c950ywan "Included decoders:\n" 49233d2500723e5594f3e7c70896ffeeef32b9c950ywan "\n", 50233d2500723e5594f3e7c70896ffeeef32b9c950ywan exec_name, 51233d2500723e5594f3e7c70896ffeeef32b9c950ywan ifaces[0].name); 52233d2500723e5594f3e7c70896ffeeef32b9c950ywan 53233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < sizeof(ifaces) / sizeof(ifaces[0]); i++) 54233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf(" %-6s - %s\n", 55233d2500723e5594f3e7c70896ffeeef32b9c950ywan ifaces[i].name, 56233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_iface_name(ifaces[i].iface)); 57233d2500723e5594f3e7c70896ffeeef32b9c950ywan 58233d2500723e5594f3e7c70896ffeeef32b9c950ywan exit(EXIT_FAILURE); 59233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 60233d2500723e5594f3e7c70896ffeeef32b9c950ywan 61233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void usage_error(const char *fmt, ...) { 62233d2500723e5594f3e7c70896ffeeef32b9c950ywan va_list ap; 63233d2500723e5594f3e7c70896ffeeef32b9c950ywan va_start(ap, fmt); 64233d2500723e5594f3e7c70896ffeeef32b9c950ywan vprintf(fmt, ap); 65233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("\n"); 66233d2500723e5594f3e7c70896ffeeef32b9c950ywan usage_exit(); 67233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 68233d2500723e5594f3e7c70896ffeeef32b9c950ywan 69233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid my_mem_dtor(vpx_codec_mmap_t *mmap) { 70233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (verbose) 71233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("freeing segment %d\n", mmap->id); 72233d2500723e5594f3e7c70896ffeeef32b9c950ywan 73233d2500723e5594f3e7c70896ffeeef32b9c950ywan free(mmap->priv); 74233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 75233d2500723e5594f3e7c70896ffeeef32b9c950ywan 76233d2500723e5594f3e7c70896ffeeef32b9c950ywanint main(int argc, char **argv) { 77233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_ctx_t decoder; 78233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_iface_t *iface = ifaces[0].iface; 79233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_iter_t iter; 80233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_dec_cfg_t cfg; 81233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_err_t res = VPX_CODEC_OK; 82233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int alloc_sz = 0; 83233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int w = 352; 84233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int h = 288; 85233d2500723e5594f3e7c70896ffeeef32b9c950ywan int i; 86233d2500723e5594f3e7c70896ffeeef32b9c950ywan 87233d2500723e5594f3e7c70896ffeeef32b9c950ywan exec_name = argv[0]; 88233d2500723e5594f3e7c70896ffeeef32b9c950ywan 89233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 1; i < argc; i++) { 90233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!strcmp(argv[i], "--codec")) { 91233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (i + 1 < argc) { 92233d2500723e5594f3e7c70896ffeeef32b9c950ywan int j, k = -1; 93233d2500723e5594f3e7c70896ffeeef32b9c950ywan 94233d2500723e5594f3e7c70896ffeeef32b9c950ywan i++; 95233d2500723e5594f3e7c70896ffeeef32b9c950ywan 96233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (j = 0; j < sizeof(ifaces) / sizeof(ifaces[0]); j++) 97233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!strcmp(ifaces[j].name, argv[i])) 98233d2500723e5594f3e7c70896ffeeef32b9c950ywan k = j; 99233d2500723e5594f3e7c70896ffeeef32b9c950ywan 100233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (k >= 0) 101233d2500723e5594f3e7c70896ffeeef32b9c950ywan iface = ifaces[k].iface; 102233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 103233d2500723e5594f3e7c70896ffeeef32b9c950ywan usage_error("Error: Unrecognized argument (%s) to --codec\n", 104233d2500723e5594f3e7c70896ffeeef32b9c950ywan argv[i]); 105233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else 106233d2500723e5594f3e7c70896ffeeef32b9c950ywan usage_error("Error: Option --codec requires argument.\n"); 107233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (!strcmp(argv[i], "-v")) 108233d2500723e5594f3e7c70896ffeeef32b9c950ywan verbose = 1; 109233d2500723e5594f3e7c70896ffeeef32b9c950ywan else if (!strcmp(argv[i], "-h")) 110233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (i + 1 < argc) { 111233d2500723e5594f3e7c70896ffeeef32b9c950ywan h = atoi(argv[++i]); 112233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else 113233d2500723e5594f3e7c70896ffeeef32b9c950ywan usage_error("Error: Option -h requires argument.\n"); 114233d2500723e5594f3e7c70896ffeeef32b9c950ywan else if (!strcmp(argv[i], "-w")) 115233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (i + 1 < argc) { 116233d2500723e5594f3e7c70896ffeeef32b9c950ywan w = atoi(argv[++i]); 117233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else 118233d2500723e5594f3e7c70896ffeeef32b9c950ywan usage_error("Error: Option -w requires argument.\n"); 119233d2500723e5594f3e7c70896ffeeef32b9c950ywan else if (!strcmp(argv[i], "--help")) 120233d2500723e5594f3e7c70896ffeeef32b9c950ywan usage_exit(); 121233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 122233d2500723e5594f3e7c70896ffeeef32b9c950ywan usage_error("Error: Unrecognized option %s\n\n", argv[i]); 123233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 124233d2500723e5594f3e7c70896ffeeef32b9c950ywan 125233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (argc == 1) 126233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("Using built-in defaults. For options, rerun with --help\n\n"); 127233d2500723e5594f3e7c70896ffeeef32b9c950ywan 128233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* XMA mode is not supported on all decoders! */ 129233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!(vpx_codec_get_caps(iface) & VPX_CODEC_CAP_XMA)) { 130233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("%s does not support XMA mode!\n", vpx_codec_iface_name(iface)); 131233d2500723e5594f3e7c70896ffeeef32b9c950ywan return EXIT_FAILURE; 132233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 133233d2500723e5594f3e7c70896ffeeef32b9c950ywan 134233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* The codec knows how much memory to allocate based on the size of the 135233d2500723e5594f3e7c70896ffeeef32b9c950ywan * encoded frames. This data can be parsed from the bitstream with 136233d2500723e5594f3e7c70896ffeeef32b9c950ywan * vpx_codec_peek_stream_info() if a bitstream is available. Otherwise, 137233d2500723e5594f3e7c70896ffeeef32b9c950ywan * a fixed size can be used that will be the upper limit on the frame 138233d2500723e5594f3e7c70896ffeeef32b9c950ywan * size the decoder can decode. 139233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 140233d2500723e5594f3e7c70896ffeeef32b9c950ywan cfg.w = w; 141233d2500723e5594f3e7c70896ffeeef32b9c950ywan cfg.h = h; 142233d2500723e5594f3e7c70896ffeeef32b9c950ywan 143233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Initialize the decoder in XMA mode. */ 144233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (vpx_codec_dec_init(&decoder, iface, &cfg, VPX_CODEC_USE_XMA)) { 145233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("Failed to initialize decoder in XMA mode: %s\n", 146233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_error(&decoder)); 147233d2500723e5594f3e7c70896ffeeef32b9c950ywan return EXIT_FAILURE; 148233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 149233d2500723e5594f3e7c70896ffeeef32b9c950ywan 150233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Iterate through the list of memory maps, allocating them with the 151233d2500723e5594f3e7c70896ffeeef32b9c950ywan * requested alignment. 152233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 153233d2500723e5594f3e7c70896ffeeef32b9c950ywan iter = NULL; 154233d2500723e5594f3e7c70896ffeeef32b9c950ywan 155233d2500723e5594f3e7c70896ffeeef32b9c950ywan do { 156233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_mmap_t mmap; 157233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int align; 158233d2500723e5594f3e7c70896ffeeef32b9c950ywan 159233d2500723e5594f3e7c70896ffeeef32b9c950ywan res = vpx_codec_get_mem_map(&decoder, &mmap, &iter); 160233d2500723e5594f3e7c70896ffeeef32b9c950ywan align = mmap.align ? mmap.align - 1 : 0; 161233d2500723e5594f3e7c70896ffeeef32b9c950ywan 162233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!res) { 163233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (verbose) 164233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("Allocating segment %u, size %lu, align %u %s\n", 165233d2500723e5594f3e7c70896ffeeef32b9c950ywan mmap.id, mmap.sz, mmap.align, 166233d2500723e5594f3e7c70896ffeeef32b9c950ywan mmap.flags & VPX_CODEC_MEM_ZERO ? "(ZEROED)" : ""); 167233d2500723e5594f3e7c70896ffeeef32b9c950ywan 168233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (mmap.flags & VPX_CODEC_MEM_ZERO) 169233d2500723e5594f3e7c70896ffeeef32b9c950ywan mmap.priv = calloc(1, mmap.sz + align); 170233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 171233d2500723e5594f3e7c70896ffeeef32b9c950ywan mmap.priv = malloc(mmap.sz + align); 172233d2500723e5594f3e7c70896ffeeef32b9c950ywan 173233d2500723e5594f3e7c70896ffeeef32b9c950ywan mmap.base = (void *)((((uintptr_t)mmap.priv) + align) & 174233d2500723e5594f3e7c70896ffeeef32b9c950ywan ~(uintptr_t)align); 175233d2500723e5594f3e7c70896ffeeef32b9c950ywan mmap.dtor = my_mem_dtor; 176233d2500723e5594f3e7c70896ffeeef32b9c950ywan alloc_sz += mmap.sz + align; 177233d2500723e5594f3e7c70896ffeeef32b9c950ywan 178233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (vpx_codec_set_mem_map(&decoder, &mmap, 1)) { 179233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("Failed to set mmap: %s\n", vpx_codec_error(&decoder)); 180233d2500723e5594f3e7c70896ffeeef32b9c950ywan return EXIT_FAILURE; 181233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 182233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (res != VPX_CODEC_LIST_END) { 183233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("Failed to get mmap: %s\n", vpx_codec_error(&decoder)); 184233d2500723e5594f3e7c70896ffeeef32b9c950ywan return EXIT_FAILURE; 185233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 186233d2500723e5594f3e7c70896ffeeef32b9c950ywan } while (res != VPX_CODEC_LIST_END); 187233d2500723e5594f3e7c70896ffeeef32b9c950ywan 188233d2500723e5594f3e7c70896ffeeef32b9c950ywan printf("%s\n %d bytes external memory required for %dx%d.\n", 189233d2500723e5594f3e7c70896ffeeef32b9c950ywan decoder.name, alloc_sz, cfg.w, cfg.h); 190233d2500723e5594f3e7c70896ffeeef32b9c950ywan vpx_codec_destroy(&decoder); 191233d2500723e5594f3e7c70896ffeeef32b9c950ywan return EXIT_SUCCESS; 192233d2500723e5594f3e7c70896ffeeef32b9c950ywan 193233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 194