Home | History | Annotate | Download | only in libvpx
      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 
     25 static char *exec_name;
     26 static int   verbose = 0;
     27 
     28 static 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 
     39 static 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 
     64 static 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 
     73 void 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 
     81 int 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