OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 10 matching lines...) Expand all Loading... |
21 | 21 |
22 #include "./args.h" | 22 #include "./args.h" |
23 #include "./tools_common.h" | 23 #include "./tools_common.h" |
24 #include "./video_writer.h" | 24 #include "./video_writer.h" |
25 | 25 |
26 #include "vpx/svc_context.h" | 26 #include "vpx/svc_context.h" |
27 #include "vpx/vp8cx.h" | 27 #include "vpx/vp8cx.h" |
28 #include "vpx/vpx_encoder.h" | 28 #include "vpx/vpx_encoder.h" |
29 #include "./vpxstats.h" | 29 #include "./vpxstats.h" |
30 | 30 |
31 static const struct arg_enum_list encoding_mode_enum[] = { | |
32 {"i", INTER_LAYER_PREDICTION_I}, | |
33 {"alt-ip", ALT_INTER_LAYER_PREDICTION_IP}, | |
34 {"ip", INTER_LAYER_PREDICTION_IP}, | |
35 {"gf", USE_GOLDEN_FRAME}, | |
36 {NULL, 0} | |
37 }; | |
38 | |
39 static const arg_def_t encoding_mode_arg = ARG_DEF_ENUM( | |
40 "m", "encoding-mode", 1, "Encoding mode algorithm", encoding_mode_enum); | |
41 static const arg_def_t skip_frames_arg = | 31 static const arg_def_t skip_frames_arg = |
42 ARG_DEF("s", "skip-frames", 1, "input frames to skip"); | 32 ARG_DEF("s", "skip-frames", 1, "input frames to skip"); |
43 static const arg_def_t frames_arg = | 33 static const arg_def_t frames_arg = |
44 ARG_DEF("f", "frames", 1, "number of frames to encode"); | 34 ARG_DEF("f", "frames", 1, "number of frames to encode"); |
45 static const arg_def_t width_arg = ARG_DEF("w", "width", 1, "source width"); | 35 static const arg_def_t width_arg = ARG_DEF("w", "width", 1, "source width"); |
46 static const arg_def_t height_arg = ARG_DEF("h", "height", 1, "source height"); | 36 static const arg_def_t height_arg = ARG_DEF("h", "height", 1, "source height"); |
47 static const arg_def_t timebase_arg = | 37 static const arg_def_t timebase_arg = |
48 ARG_DEF("t", "timebase", 1, "timebase (num/den)"); | 38 ARG_DEF("t", "timebase", 1, "timebase (num/den)"); |
49 static const arg_def_t bitrate_arg = ARG_DEF( | 39 static const arg_def_t bitrate_arg = ARG_DEF( |
50 "b", "target-bitrate", 1, "encoding bitrate, in kilobits per second"); | 40 "b", "target-bitrate", 1, "encoding bitrate, in kilobits per second"); |
51 static const arg_def_t layers_arg = | 41 static const arg_def_t layers_arg = |
52 ARG_DEF("l", "layers", 1, "number of SVC layers"); | 42 ARG_DEF("l", "layers", 1, "number of SVC layers"); |
53 static const arg_def_t kf_dist_arg = | 43 static const arg_def_t kf_dist_arg = |
54 ARG_DEF("k", "kf-dist", 1, "number of frames between keyframes"); | 44 ARG_DEF("k", "kf-dist", 1, "number of frames between keyframes"); |
55 static const arg_def_t scale_factors_arg = | 45 static const arg_def_t scale_factors_arg = |
56 ARG_DEF("r", "scale-factors", 1, "scale factors (lowest to highest layer)"); | 46 ARG_DEF("r", "scale-factors", 1, "scale factors (lowest to highest layer)"); |
57 static const arg_def_t quantizers_arg = | 47 static const arg_def_t quantizers_arg = |
58 ARG_DEF("q", "quantizers", 1, "quantizers for non key frames, also will " | 48 ARG_DEF("q", "quantizers", 1, "quantizers for non key frames, also will " |
59 "be applied to key frames if -qn is not specified (lowest to " | 49 "be applied to key frames if -qn is not specified (lowest to " |
60 "highest layer)"); | 50 "highest layer)"); |
61 static const arg_def_t quantizers_keyframe_arg = | |
62 ARG_DEF("qn", "quantizers-keyframe", 1, "quantizers for key frames (lowest " | |
63 "to highest layer)"); | |
64 static const arg_def_t passes_arg = | 51 static const arg_def_t passes_arg = |
65 ARG_DEF("p", "passes", 1, "Number of passes (1/2)"); | 52 ARG_DEF("p", "passes", 1, "Number of passes (1/2)"); |
66 static const arg_def_t pass_arg = | 53 static const arg_def_t pass_arg = |
67 ARG_DEF(NULL, "pass", 1, "Pass to execute (1/2)"); | 54 ARG_DEF(NULL, "pass", 1, "Pass to execute (1/2)"); |
68 static const arg_def_t fpf_name_arg = | 55 static const arg_def_t fpf_name_arg = |
69 ARG_DEF(NULL, "fpf", 1, "First pass statistics file name"); | 56 ARG_DEF(NULL, "fpf", 1, "First pass statistics file name"); |
70 static const arg_def_t min_q_arg = | 57 static const arg_def_t min_q_arg = |
71 ARG_DEF(NULL, "min-q", 1, "Minimum quantizer"); | 58 ARG_DEF(NULL, "min-q", 1, "Minimum quantizer"); |
72 static const arg_def_t max_q_arg = | 59 static const arg_def_t max_q_arg = |
73 ARG_DEF(NULL, "max-q", 1, "Maximum quantizer"); | 60 ARG_DEF(NULL, "max-q", 1, "Maximum quantizer"); |
74 static const arg_def_t min_bitrate_arg = | 61 static const arg_def_t min_bitrate_arg = |
75 ARG_DEF(NULL, "min-bitrate", 1, "Minimum bitrate"); | 62 ARG_DEF(NULL, "min-bitrate", 1, "Minimum bitrate"); |
76 static const arg_def_t max_bitrate_arg = | 63 static const arg_def_t max_bitrate_arg = |
77 ARG_DEF(NULL, "max-bitrate", 1, "Maximum bitrate"); | 64 ARG_DEF(NULL, "max-bitrate", 1, "Maximum bitrate"); |
78 | 65 |
79 static const arg_def_t *svc_args[] = { | 66 static const arg_def_t *svc_args[] = { |
80 &encoding_mode_arg, &frames_arg, &width_arg, &height_arg, | 67 &frames_arg, &width_arg, &height_arg, |
81 &timebase_arg, &bitrate_arg, &skip_frames_arg, &layers_arg, | 68 &timebase_arg, &bitrate_arg, &skip_frames_arg, &layers_arg, |
82 &kf_dist_arg, &scale_factors_arg, &quantizers_arg, | 69 &kf_dist_arg, &scale_factors_arg, &quantizers_arg, &passes_arg, |
83 &quantizers_keyframe_arg, &passes_arg, &pass_arg, | 70 &pass_arg, &fpf_name_arg, &min_q_arg, &max_q_arg, |
84 &fpf_name_arg, &min_q_arg, &max_q_arg, &min_bitrate_arg, | 71 &min_bitrate_arg, &max_bitrate_arg, NULL |
85 &max_bitrate_arg, NULL | |
86 }; | 72 }; |
87 | 73 |
88 static const SVC_ENCODING_MODE default_encoding_mode = | |
89 INTER_LAYER_PREDICTION_IP; | |
90 static const uint32_t default_frames_to_skip = 0; | 74 static const uint32_t default_frames_to_skip = 0; |
91 static const uint32_t default_frames_to_code = 60 * 60; | 75 static const uint32_t default_frames_to_code = 60 * 60; |
92 static const uint32_t default_width = 1920; | 76 static const uint32_t default_width = 1920; |
93 static const uint32_t default_height = 1080; | 77 static const uint32_t default_height = 1080; |
94 static const uint32_t default_timebase_num = 1; | 78 static const uint32_t default_timebase_num = 1; |
95 static const uint32_t default_timebase_den = 60; | 79 static const uint32_t default_timebase_den = 60; |
96 static const uint32_t default_bitrate = 1000; | 80 static const uint32_t default_bitrate = 1000; |
97 static const uint32_t default_spatial_layers = 5; | 81 static const uint32_t default_spatial_layers = 5; |
98 static const uint32_t default_kf_dist = 100; | 82 static const uint32_t default_kf_dist = 100; |
99 | 83 |
(...skipping 28 matching lines...) Expand all Loading... |
128 vpx_codec_err_t res; | 112 vpx_codec_err_t res; |
129 int passes = 0; | 113 int passes = 0; |
130 int pass = 0; | 114 int pass = 0; |
131 const char *fpf_file_name = NULL; | 115 const char *fpf_file_name = NULL; |
132 unsigned int min_bitrate = 0; | 116 unsigned int min_bitrate = 0; |
133 unsigned int max_bitrate = 0; | 117 unsigned int max_bitrate = 0; |
134 | 118 |
135 // initialize SvcContext with parameters that will be passed to vpx_svc_init | 119 // initialize SvcContext with parameters that will be passed to vpx_svc_init |
136 svc_ctx->log_level = SVC_LOG_DEBUG; | 120 svc_ctx->log_level = SVC_LOG_DEBUG; |
137 svc_ctx->spatial_layers = default_spatial_layers; | 121 svc_ctx->spatial_layers = default_spatial_layers; |
138 svc_ctx->encoding_mode = default_encoding_mode; | |
139 | 122 |
140 // start with default encoder configuration | 123 // start with default encoder configuration |
141 res = vpx_codec_enc_config_default(vpx_codec_vp9_cx(), enc_cfg, 0); | 124 res = vpx_codec_enc_config_default(vpx_codec_vp9_cx(), enc_cfg, 0); |
142 if (res) { | 125 if (res) { |
143 die("Failed to get config: %s\n", vpx_codec_err_to_string(res)); | 126 die("Failed to get config: %s\n", vpx_codec_err_to_string(res)); |
144 } | 127 } |
145 // update enc_cfg with app default values | 128 // update enc_cfg with app default values |
146 enc_cfg->g_w = default_width; | 129 enc_cfg->g_w = default_width; |
147 enc_cfg->g_h = default_height; | 130 enc_cfg->g_h = default_height; |
148 enc_cfg->g_timebase.num = default_timebase_num; | 131 enc_cfg->g_timebase.num = default_timebase_num; |
149 enc_cfg->g_timebase.den = default_timebase_den; | 132 enc_cfg->g_timebase.den = default_timebase_den; |
150 enc_cfg->rc_target_bitrate = default_bitrate; | 133 enc_cfg->rc_target_bitrate = default_bitrate; |
151 enc_cfg->kf_min_dist = default_kf_dist; | 134 enc_cfg->kf_min_dist = default_kf_dist; |
152 enc_cfg->kf_max_dist = default_kf_dist; | 135 enc_cfg->kf_max_dist = default_kf_dist; |
153 enc_cfg->rc_end_usage = VPX_CQ; | 136 enc_cfg->rc_end_usage = VPX_CQ; |
154 | 137 |
155 // initialize AppInput with default values | 138 // initialize AppInput with default values |
156 app_input->frames_to_code = default_frames_to_code; | 139 app_input->frames_to_code = default_frames_to_code; |
157 app_input->frames_to_skip = default_frames_to_skip; | 140 app_input->frames_to_skip = default_frames_to_skip; |
158 | 141 |
159 // process command line options | 142 // process command line options |
160 argv = argv_dup(argc - 1, argv_ + 1); | 143 argv = argv_dup(argc - 1, argv_ + 1); |
161 for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) { | 144 for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) { |
162 arg.argv_step = 1; | 145 arg.argv_step = 1; |
163 | 146 |
164 if (arg_match(&arg, &encoding_mode_arg, argi)) { | 147 if (arg_match(&arg, &frames_arg, argi)) { |
165 svc_ctx->encoding_mode = arg_parse_enum_or_int(&arg); | |
166 } else if (arg_match(&arg, &frames_arg, argi)) { | |
167 app_input->frames_to_code = arg_parse_uint(&arg); | 148 app_input->frames_to_code = arg_parse_uint(&arg); |
168 } else if (arg_match(&arg, &width_arg, argi)) { | 149 } else if (arg_match(&arg, &width_arg, argi)) { |
169 enc_cfg->g_w = arg_parse_uint(&arg); | 150 enc_cfg->g_w = arg_parse_uint(&arg); |
170 } else if (arg_match(&arg, &height_arg, argi)) { | 151 } else if (arg_match(&arg, &height_arg, argi)) { |
171 enc_cfg->g_h = arg_parse_uint(&arg); | 152 enc_cfg->g_h = arg_parse_uint(&arg); |
172 } else if (arg_match(&arg, &timebase_arg, argi)) { | 153 } else if (arg_match(&arg, &timebase_arg, argi)) { |
173 enc_cfg->g_timebase = arg_parse_rational(&arg); | 154 enc_cfg->g_timebase = arg_parse_rational(&arg); |
174 } else if (arg_match(&arg, &bitrate_arg, argi)) { | 155 } else if (arg_match(&arg, &bitrate_arg, argi)) { |
175 enc_cfg->rc_target_bitrate = arg_parse_uint(&arg); | 156 enc_cfg->rc_target_bitrate = arg_parse_uint(&arg); |
176 } else if (arg_match(&arg, &skip_frames_arg, argi)) { | 157 } else if (arg_match(&arg, &skip_frames_arg, argi)) { |
177 app_input->frames_to_skip = arg_parse_uint(&arg); | 158 app_input->frames_to_skip = arg_parse_uint(&arg); |
178 } else if (arg_match(&arg, &layers_arg, argi)) { | 159 } else if (arg_match(&arg, &layers_arg, argi)) { |
179 svc_ctx->spatial_layers = arg_parse_uint(&arg); | 160 svc_ctx->spatial_layers = arg_parse_uint(&arg); |
180 } else if (arg_match(&arg, &kf_dist_arg, argi)) { | 161 } else if (arg_match(&arg, &kf_dist_arg, argi)) { |
181 enc_cfg->kf_min_dist = arg_parse_uint(&arg); | 162 enc_cfg->kf_min_dist = arg_parse_uint(&arg); |
182 enc_cfg->kf_max_dist = enc_cfg->kf_min_dist; | 163 enc_cfg->kf_max_dist = enc_cfg->kf_min_dist; |
183 } else if (arg_match(&arg, &scale_factors_arg, argi)) { | 164 } else if (arg_match(&arg, &scale_factors_arg, argi)) { |
184 vpx_svc_set_scale_factors(svc_ctx, arg.val); | 165 vpx_svc_set_scale_factors(svc_ctx, arg.val); |
185 } else if (arg_match(&arg, &quantizers_arg, argi)) { | 166 } else if (arg_match(&arg, &quantizers_arg, argi)) { |
186 vpx_svc_set_quantizers(svc_ctx, arg.val, 0); | 167 vpx_svc_set_quantizers(svc_ctx, arg.val); |
187 } else if (arg_match(&arg, &quantizers_keyframe_arg, argi)) { | |
188 vpx_svc_set_quantizers(svc_ctx, arg.val, 1); | |
189 } else if (arg_match(&arg, &passes_arg, argi)) { | 168 } else if (arg_match(&arg, &passes_arg, argi)) { |
190 passes = arg_parse_uint(&arg); | 169 passes = arg_parse_uint(&arg); |
191 if (passes < 1 || passes > 2) { | 170 if (passes < 1 || passes > 2) { |
192 die("Error: Invalid number of passes (%d)\n", passes); | 171 die("Error: Invalid number of passes (%d)\n", passes); |
193 } | 172 } |
194 } else if (arg_match(&arg, &pass_arg, argi)) { | 173 } else if (arg_match(&arg, &pass_arg, argi)) { |
195 pass = arg_parse_uint(&arg); | 174 pass = arg_parse_uint(&arg); |
196 if (pass < 1 || pass > 2) { | 175 if (pass < 1 || pass > 2) { |
197 die("Error: Invalid pass selected (%d)\n", pass); | 176 die("Error: Invalid pass selected (%d)\n", pass); |
198 } | 177 } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 app_input->input_filename = argv[0]; | 242 app_input->input_filename = argv[0]; |
264 app_input->output_filename = argv[1]; | 243 app_input->output_filename = argv[1]; |
265 free(argv); | 244 free(argv); |
266 | 245 |
267 if (enc_cfg->g_w < 16 || enc_cfg->g_w % 2 || enc_cfg->g_h < 16 || | 246 if (enc_cfg->g_w < 16 || enc_cfg->g_w % 2 || enc_cfg->g_h < 16 || |
268 enc_cfg->g_h % 2) | 247 enc_cfg->g_h % 2) |
269 die("Invalid resolution: %d x %d\n", enc_cfg->g_w, enc_cfg->g_h); | 248 die("Invalid resolution: %d x %d\n", enc_cfg->g_w, enc_cfg->g_h); |
270 | 249 |
271 printf( | 250 printf( |
272 "Codec %s\nframes: %d, skip: %d\n" | 251 "Codec %s\nframes: %d, skip: %d\n" |
273 "mode: %d, layers: %d\n" | 252 "layers: %d\n" |
274 "width %d, height: %d,\n" | 253 "width %d, height: %d,\n" |
275 "num: %d, den: %d, bitrate: %d,\n" | 254 "num: %d, den: %d, bitrate: %d,\n" |
276 "gop size: %d\n", | 255 "gop size: %d\n", |
277 vpx_codec_iface_name(vpx_codec_vp9_cx()), app_input->frames_to_code, | 256 vpx_codec_iface_name(vpx_codec_vp9_cx()), app_input->frames_to_code, |
278 app_input->frames_to_skip, svc_ctx->encoding_mode, | 257 app_input->frames_to_skip, |
279 svc_ctx->spatial_layers, enc_cfg->g_w, enc_cfg->g_h, | 258 svc_ctx->spatial_layers, enc_cfg->g_w, enc_cfg->g_h, |
280 enc_cfg->g_timebase.num, enc_cfg->g_timebase.den, | 259 enc_cfg->g_timebase.num, enc_cfg->g_timebase.den, |
281 enc_cfg->rc_target_bitrate, enc_cfg->kf_max_dist); | 260 enc_cfg->rc_target_bitrate, enc_cfg->kf_max_dist); |
282 } | 261 } |
283 | 262 |
284 int main(int argc, const char **argv) { | 263 int main(int argc, const char **argv) { |
285 AppInput app_input = {0}; | 264 AppInput app_input = {0}; |
286 VpxVideoWriter *writer = NULL; | 265 VpxVideoWriter *writer = NULL; |
287 VpxVideoInfo info = {0}; | 266 VpxVideoInfo info = {0}; |
288 vpx_codec_ctx_t codec; | 267 vpx_codec_ctx_t codec; |
289 vpx_codec_enc_cfg_t enc_cfg; | 268 vpx_codec_enc_cfg_t enc_cfg; |
290 SvcContext svc_ctx; | 269 SvcContext svc_ctx; |
291 uint32_t i; | 270 uint32_t i; |
292 uint32_t frame_cnt = 0; | 271 uint32_t frame_cnt = 0; |
293 vpx_image_t raw; | 272 vpx_image_t raw; |
294 vpx_codec_err_t res; | 273 vpx_codec_err_t res; |
295 int pts = 0; /* PTS starts at 0 */ | 274 int pts = 0; /* PTS starts at 0 */ |
296 int frame_duration = 1; /* 1 timebase tick per frame */ | 275 int frame_duration = 1; /* 1 timebase tick per frame */ |
297 FILE *infile = NULL; | 276 FILE *infile = NULL; |
298 int end_of_stream = 0; | 277 int end_of_stream = 0; |
| 278 int frame_size; |
299 | 279 |
300 memset(&svc_ctx, 0, sizeof(svc_ctx)); | 280 memset(&svc_ctx, 0, sizeof(svc_ctx)); |
301 svc_ctx.log_print = 1; | 281 svc_ctx.log_print = 1; |
302 exec_name = argv[0]; | 282 exec_name = argv[0]; |
303 parse_command_line(argc, argv, &app_input, &svc_ctx, &enc_cfg); | 283 parse_command_line(argc, argv, &app_input, &svc_ctx, &enc_cfg); |
304 | 284 |
305 // Allocate image buffer | 285 // Allocate image buffer |
306 if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, enc_cfg.g_w, enc_cfg.g_h, 32)) | 286 if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, enc_cfg.g_w, enc_cfg.g_h, 32)) |
307 die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h); | 287 die("Failed to allocate image %dx%d\n", enc_cfg.g_w, enc_cfg.g_h); |
308 | 288 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 end_of_stream = 1; | 324 end_of_stream = 1; |
345 } | 325 } |
346 | 326 |
347 res = vpx_svc_encode(&svc_ctx, &codec, (end_of_stream ? NULL : &raw), | 327 res = vpx_svc_encode(&svc_ctx, &codec, (end_of_stream ? NULL : &raw), |
348 pts, frame_duration, VPX_DL_GOOD_QUALITY); | 328 pts, frame_duration, VPX_DL_GOOD_QUALITY); |
349 printf("%s", vpx_svc_get_message(&svc_ctx)); | 329 printf("%s", vpx_svc_get_message(&svc_ctx)); |
350 if (res != VPX_CODEC_OK) { | 330 if (res != VPX_CODEC_OK) { |
351 die_codec(&codec, "Failed to encode frame"); | 331 die_codec(&codec, "Failed to encode frame"); |
352 } | 332 } |
353 if (!(app_input.passes == 2 && app_input.pass == 1)) { | 333 if (!(app_input.passes == 2 && app_input.pass == 1)) { |
354 if (vpx_svc_get_frame_size(&svc_ctx) > 0) { | 334 while ((frame_size = vpx_svc_get_frame_size(&svc_ctx)) > 0) { |
355 vpx_video_writer_write_frame(writer, | 335 vpx_video_writer_write_frame(writer, |
356 vpx_svc_get_buffer(&svc_ctx), | 336 vpx_svc_get_buffer(&svc_ctx), |
357 vpx_svc_get_frame_size(&svc_ctx), | 337 frame_size, pts); |
358 pts); | |
359 } | 338 } |
360 } | 339 } |
361 if (vpx_svc_get_rc_stats_buffer_size(&svc_ctx) > 0) { | 340 if (vpx_svc_get_rc_stats_buffer_size(&svc_ctx) > 0) { |
362 stats_write(&app_input.rc_stats, | 341 stats_write(&app_input.rc_stats, |
363 vpx_svc_get_rc_stats_buffer(&svc_ctx), | 342 vpx_svc_get_rc_stats_buffer(&svc_ctx), |
364 vpx_svc_get_rc_stats_buffer_size(&svc_ctx)); | 343 vpx_svc_get_rc_stats_buffer_size(&svc_ctx)); |
365 } | 344 } |
366 if (!end_of_stream) { | 345 if (!end_of_stream) { |
367 ++frame_cnt; | 346 ++frame_cnt; |
368 pts += frame_duration; | 347 pts += frame_duration; |
(...skipping 14 matching lines...) Expand all Loading... |
383 | 362 |
384 vpx_img_free(&raw); | 363 vpx_img_free(&raw); |
385 | 364 |
386 // display average size, psnr | 365 // display average size, psnr |
387 printf("%s", vpx_svc_dump_statistics(&svc_ctx)); | 366 printf("%s", vpx_svc_dump_statistics(&svc_ctx)); |
388 | 367 |
389 vpx_svc_release(&svc_ctx); | 368 vpx_svc_release(&svc_ctx); |
390 | 369 |
391 return EXIT_SUCCESS; | 370 return EXIT_SUCCESS; |
392 } | 371 } |
OLD | NEW |