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