• 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_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 
usage_exit(void)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 
usage_error(const char * fmt,...)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 
my_mem_dtor(vpx_codec_mmap_t * mmap)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 
main(int argc,char ** argv)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