• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
usage_exit(void)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 
usage_error(const char * fmt,...)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 
my_mem_dtor(vpx_codec_mmap_t * mmap)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 
main(int argc,char ** argv)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