| 1 | /* |
| 2 | Copyright (c) 2012, Broadcom Europe Ltd |
| 3 | All rights reserved. |
| 4 | |
| 5 | Redistribution and use in source and binary forms, with or without |
| 6 | modification, are permitted provided that the following conditions are met: |
| 7 | * Redistributions of source code must retain the above copyright |
| 8 | notice, this list of conditions and the following disclaimer. |
| 9 | * Redistributions in binary form must reproduce the above copyright |
| 10 | notice, this list of conditions and the following disclaimer in the |
| 11 | documentation and/or other materials provided with the distribution. |
| 12 | * Neither the name of the copyright holder nor the |
| 13 | names of its contributors may be used to endorse or promote products |
| 14 | derived from this software without specific prior written permission. |
| 15 | |
| 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY |
| 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 26 | */ |
| 27 | |
| 28 | #include "brcmjpeg.h" |
| 29 | #include <sys/time.h> |
| 30 | #include <stdlib.h> |
| 31 | #include <string.h> |
| 32 | #include <errno.h> |
| 33 | #include <stdio.h> |
| 34 | #include <stdint.h> |
| 35 | #include <user-vcsm.h> |
| 36 | |
| 37 | #define MAX_WIDTH 5000 |
| 38 | #define MAX_HEIGHT 5000 |
| 39 | #define MAX_ENCODED (15*1024*1024) |
| 40 | #define MAX_DECODED (MAX_WIDTH*MAX_HEIGHT*2) |
| 41 | |
| 42 | static uint8_t encodedInBuf[MAX_ENCODED]; |
| 43 | static uint8_t encodedOutBuf[MAX_ENCODED]; |
| 44 | static uint8_t decodedBuf[MAX_DECODED]; |
| 45 | static char outFileName[2048]; |
| 46 | |
| 47 | int64_t get_time_microsec(void) |
| 48 | { |
| 49 | struct timeval now; |
| 50 | gettimeofday(&now, NULL); |
| 51 | return now.tv_sec * 1000000LL + now.tv_usec; |
| 52 | } |
| 53 | |
| 54 | int main(int argc, char **argv) |
| 55 | { |
| 56 | BRCMJPEG_STATUS_T status; |
| 57 | BRCMJPEG_REQUEST_T enc_request, dec_request; |
| 58 | BRCMJPEG_T *enc = 0, *dec = 0; |
| 59 | int64_t start, stop, time_dec = 0, time_enc = 0; |
| 60 | unsigned int count = 1, format = PIXEL_FORMAT_YUYV; |
| 61 | unsigned int use_vcsm = 0, handle = 0, vc_handle = 0; |
| 62 | int i, arg = 1, help = 0; |
| 63 | |
| 64 | // Parse command line arguments |
| 65 | while (arg < argc && argv[arg][0] == '-') |
| 66 | { |
| 67 | if (!strcmp(argv[arg], "-n" )) |
| 68 | { |
| 69 | if (++arg >= argc || sscanf(argv[arg++], "%u" , &count) != 1) |
| 70 | arg = argc; |
| 71 | } |
| 72 | else if (!strcmp(argv[arg], "-f" )) |
| 73 | { |
| 74 | if (++arg >= argc || sscanf(argv[arg++], "%u" , &format) != 1) |
| 75 | arg = argc; |
| 76 | } |
| 77 | else if (!strcmp(argv[arg], "-s" )) |
| 78 | { |
| 79 | use_vcsm = 1; |
| 80 | arg++; |
| 81 | } |
| 82 | else if (!strcmp(argv[arg], "-h" )) |
| 83 | { |
| 84 | help = 1; |
| 85 | break; |
| 86 | } |
| 87 | else |
| 88 | { |
| 89 | arg = argc; |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | if (arg == argc || help) |
| 94 | { |
| 95 | if (!help) fprintf(stderr, "invalid arguments\n" ); |
| 96 | fprintf(stderr, "usage: %s [options] file1 ... fileN\n" , argv[0]); |
| 97 | fprintf(stderr, "options list:\n" ); |
| 98 | fprintf(stderr, " -h : help\n" ); |
| 99 | fprintf(stderr, " -n <N> : process each file N times\n" ); |
| 100 | fprintf(stderr, " -f <N> : force color format\n" ); |
| 101 | fprintf(stderr, " -s : use shared-memory for intermediate buffer\n" ); |
| 102 | return !help; |
| 103 | } |
| 104 | |
| 105 | if (use_vcsm) |
| 106 | { |
| 107 | if (vcsm_init() < 0) |
| 108 | { |
| 109 | fprintf(stderr, "failed to initialise vcsm\n" ); |
| 110 | return 1; |
| 111 | } |
| 112 | |
| 113 | handle = vcsm_malloc_cache(MAX_DECODED, VCSM_CACHE_TYPE_HOST, "brcmjpeg-test" ); |
| 114 | if (!handle) |
| 115 | { |
| 116 | fprintf(stderr, "failed to alloc vcsm buffer\n" ); |
| 117 | vcsm_exit(); |
| 118 | return 1; |
| 119 | } |
| 120 | |
| 121 | vc_handle = vcsm_vc_hdl_from_hdl(handle); |
| 122 | |
| 123 | fprintf(stderr, "decodedBuf handle %u vc_handle %u\n" , handle, vc_handle); |
| 124 | } |
| 125 | |
| 126 | // Setup of the dec / enc requests |
| 127 | memset(&enc_request, 0, sizeof(enc_request)); |
| 128 | memset(&dec_request, 0, sizeof(dec_request)); |
| 129 | dec_request.input = encodedInBuf; |
| 130 | dec_request.output = use_vcsm ? NULL : decodedBuf; |
| 131 | dec_request.output_handle = use_vcsm ? vc_handle : 0; |
| 132 | dec_request.output_alloc_size = MAX_DECODED; |
| 133 | enc_request.input = dec_request.output; |
| 134 | enc_request.input_handle = dec_request.output_handle; |
| 135 | enc_request.output = encodedOutBuf; |
| 136 | enc_request.output_alloc_size = sizeof(encodedOutBuf); |
| 137 | enc_request.quality = 75; |
| 138 | enc_request.pixel_format = dec_request.pixel_format = format; |
| 139 | |
| 140 | status = brcmjpeg_create(BRCMJPEG_TYPE_ENCODER, &enc); |
| 141 | if (status != BRCMJPEG_SUCCESS) |
| 142 | { |
| 143 | fprintf(stderr, "could not create encoder\n" ); |
| 144 | return 1; |
| 145 | } |
| 146 | status = brcmjpeg_create(BRCMJPEG_TYPE_DECODER, &dec); |
| 147 | if (status != BRCMJPEG_SUCCESS) |
| 148 | { |
| 149 | fprintf(stderr, "could not create decoder\n" ); |
| 150 | brcmjpeg_release(enc); |
| 151 | return 1; |
| 152 | } |
| 153 | |
| 154 | for (i = arg; i < argc; i++) |
| 155 | { |
| 156 | unsigned int j; |
| 157 | fprintf(stderr, "processing %s\n" , argv[i]); |
| 158 | |
| 159 | FILE *file_in = fopen(argv[i], "rb" ); |
| 160 | if (!file_in) { |
| 161 | fprintf(stderr, "could not open file %s\n" , argv[i]); |
| 162 | continue; |
| 163 | } |
| 164 | snprintf(outFileName, sizeof(outFileName), "%s.out" , argv[i]); |
| 165 | FILE *file_out = fopen(outFileName, "wb+" ); |
| 166 | if (!file_out) { |
| 167 | fprintf(stderr, "could not open file %s\n" , outFileName); |
| 168 | fclose(file_in); |
| 169 | continue; |
| 170 | } |
| 171 | dec_request.input_size = fread(encodedInBuf, 1, sizeof(encodedInBuf), file_in); |
| 172 | |
| 173 | for (j = 0; j < count; j++) |
| 174 | { |
| 175 | dec_request.buffer_width = 0; |
| 176 | dec_request.buffer_height = 0; |
| 177 | |
| 178 | start = get_time_microsec(); |
| 179 | status = brcmjpeg_process(dec, &dec_request); |
| 180 | stop = get_time_microsec(); |
| 181 | if (status != BRCMJPEG_SUCCESS) { |
| 182 | fprintf(stderr, "could not decode %s\n" , argv[i]); |
| 183 | break; |
| 184 | } |
| 185 | |
| 186 | fprintf(stderr, "decoded %ix%i(%ix%i), %i bytes in %lldus\n" , |
| 187 | dec_request.width, dec_request.height, |
| 188 | dec_request.buffer_width, dec_request.buffer_height, |
| 189 | dec_request.input_size, stop - start); |
| 190 | time_dec += stop - start; |
| 191 | |
| 192 | enc_request.input_size = dec_request.output_size; |
| 193 | enc_request.width = dec_request.width; |
| 194 | enc_request.height = dec_request.height; |
| 195 | enc_request.buffer_width = dec_request.buffer_width; |
| 196 | enc_request.buffer_height = dec_request.buffer_height; |
| 197 | |
| 198 | start = get_time_microsec(); |
| 199 | status = brcmjpeg_process(enc, &enc_request); |
| 200 | stop = get_time_microsec(); |
| 201 | if (status != BRCMJPEG_SUCCESS) { |
| 202 | fprintf(stderr, "could not encode %s\n" , outFileName); |
| 203 | break; |
| 204 | } |
| 205 | |
| 206 | fprintf(stderr, "encoded %ix%i(%ix%i), %i bytes in %lldus\n" , |
| 207 | enc_request.width, enc_request.height, |
| 208 | enc_request.buffer_width, enc_request.buffer_height, |
| 209 | enc_request.output_size, stop - start); |
| 210 | time_enc += stop - start; |
| 211 | } |
| 212 | |
| 213 | if (status != BRCMJPEG_SUCCESS) |
| 214 | continue; |
| 215 | |
| 216 | fwrite(enc_request.output, 1, enc_request.output_size, file_out); |
| 217 | fclose(file_out); |
| 218 | fclose(file_in); |
| 219 | |
| 220 | fprintf(stderr, "decode times %lldus (%lldus per run)\n" , |
| 221 | time_dec, time_dec / count); |
| 222 | fprintf(stderr, "encode times %lldus (%lldus per run)\n" , |
| 223 | time_enc, time_enc / count); |
| 224 | } |
| 225 | |
| 226 | brcmjpeg_release(dec); |
| 227 | brcmjpeg_release(enc); |
| 228 | |
| 229 | if (use_vcsm) |
| 230 | { |
| 231 | vcsm_free(handle); |
| 232 | vcsm_exit(); |
| 233 | } |
| 234 | |
| 235 | return 0; |
| 236 | } |
| 237 | |