Commit 0b993846 authored by Sebastien Alaiwan's avatar Sebastien Alaiwan
Browse files

Simplify FOREACH_STREAM

With C99 we can now declare iterators inside the 'for' statements,
allowing a better syntax for this macro.
This new syntax accepts #if/#endif inside the loop body,
and makes explicit, at loop body level, what the iterator name is.

Change-Id: Icbd363a34a9264ff566ee8057c08a705736b509f
parent 2e5933f5
......@@ -1087,13 +1087,9 @@ static int parse_stream_params(struct AvxEncoderConfig *global,
return eos_mark_found;
}
#define FOREACH_STREAM(func) \
do { \
struct stream_state *stream; \
for (stream = streams; stream; stream = stream->next) { \
func; \
} \
} while (0)
#define FOREACH_STREAM(iterator, list) \
for (struct stream_state *iterator = list; iterator; \
iterator = iterator->next)
static void validate_stream_config(const struct stream_state *stream,
const struct AvxEncoderConfig *global) {
......@@ -1753,8 +1749,10 @@ int main(int argc, const char **argv_) {
if (argi[0][0] == '-' && argi[0][1])
die("Error: Unrecognized option %s\n", *argi);
FOREACH_STREAM(check_encoder_config(global.disable_warning_prompt, &global,
&stream->config.cfg););
FOREACH_STREAM(stream, streams) {
check_encoder_config(global.disable_warning_prompt, &global,
&stream->config.cfg);
}
/* Handle non-option arguments */
input.filename = argv[0];
......@@ -1776,13 +1774,13 @@ int main(int argc, const char **argv_) {
* the data from the first stream's configuration.
*/
if (!input.width || !input.height) {
FOREACH_STREAM({
FOREACH_STREAM(stream, streams) {
if (stream->config.cfg.g_w && stream->config.cfg.g_h) {
input.width = stream->config.cfg.g_w;
input.height = stream->config.cfg.g_h;
break;
}
});
};
}
/* Update stream configurations from the input file's parameters */
......@@ -1797,20 +1795,21 @@ int main(int argc, const char **argv_) {
* to be the same as the codec bit-depth.
*/
if (!input.bit_depth) {
FOREACH_STREAM({
FOREACH_STREAM(stream, streams) {
if (stream->config.cfg.g_input_bit_depth)
input.bit_depth = stream->config.cfg.g_input_bit_depth;
else
input.bit_depth = stream->config.cfg.g_input_bit_depth =
(int)stream->config.cfg.g_bit_depth;
});
}
if (input.bit_depth > 8) input.fmt |= AOM_IMG_FMT_HIGHBITDEPTH;
} else {
FOREACH_STREAM(
{ stream->config.cfg.g_input_bit_depth = input.bit_depth; });
FOREACH_STREAM(stream, streams) {
stream->config.cfg.g_input_bit_depth = input.bit_depth;
}
}
FOREACH_STREAM({
FOREACH_STREAM(stream, streams) {
if (input.fmt != AOM_IMG_FMT_I420 && input.fmt != AOM_IMG_FMT_I42016) {
/* Automatically upgrade if input is non-4:2:0 but a 4:2:0 profile
was selected. */
......@@ -1855,31 +1854,34 @@ int main(int argc, const char **argv_) {
"match input format.\n",
stream->config.cfg.g_profile);
}
});
}
FOREACH_STREAM(set_stream_dimensions(stream, input.width, input.height));
FOREACH_STREAM(validate_stream_config(stream, &global));
FOREACH_STREAM(stream, streams) {
set_stream_dimensions(stream, input.width, input.height);
}
FOREACH_STREAM(stream, streams) { validate_stream_config(stream, &global); }
/* Ensure that --passes and --pass are consistent. If --pass is set and
* --passes=2, ensure --fpf was set.
*/
if (global.pass && global.passes == 2)
FOREACH_STREAM({
if (global.pass && global.passes == 2) {
FOREACH_STREAM(stream, streams) {
if (!stream->config.stats_fn)
die("Stream %d: Must specify --fpf when --pass=%d"
" and --passes=2\n",
stream->index, global.pass);
});
}
}
#if !CONFIG_WEBM_IO
FOREACH_STREAM({
FOREACH_STREAM(stream, streams) {
if (stream->config.write_webm) {
stream->config.write_webm = 0;
warn(
"aomenc was compiled without WebM container support."
"Producing IVF output");
}
});
}
#endif
/* Use the frame rate from the file only if none was specified
......@@ -1888,31 +1890,39 @@ int main(int argc, const char **argv_) {
if (!global.have_framerate) {
global.framerate.num = input.framerate.numerator;
global.framerate.den = input.framerate.denominator;
FOREACH_STREAM(stream->config.cfg.g_timebase.den = global.framerate.num;
stream->config.cfg.g_timebase.num = global.framerate.den);
FOREACH_STREAM(stream, streams) {
stream->config.cfg.g_timebase.den = global.framerate.num;
stream->config.cfg.g_timebase.num = global.framerate.den;
}
}
/* Show configuration */
if (global.verbose && pass == 0)
FOREACH_STREAM(show_stream_config(stream, &global, &input));
if (global.verbose && pass == 0) {
FOREACH_STREAM(stream, streams) {
show_stream_config(stream, &global, &input);
}
}
if (pass == (global.pass ? global.pass - 1 : 0)) {
if (input.file_type == FILE_TYPE_Y4M)
/*The Y4M reader does its own allocation.
Just initialize this here to avoid problems if we never read any
frames.*/
frames.*/
memset(&raw, 0, sizeof(raw));
else
aom_img_alloc(&raw, input.fmt, input.width, input.height, 32);
FOREACH_STREAM(stream->rate_hist = init_rate_histogram(
&stream->config.cfg, &global.framerate));
FOREACH_STREAM(stream, streams) {
stream->rate_hist =
init_rate_histogram(&stream->config.cfg, &global.framerate);
}
}
FOREACH_STREAM(setup_pass(stream, &global, pass));
FOREACH_STREAM(
open_output_file(stream, &global, &input.pixel_aspect_ratio));
FOREACH_STREAM(initialize_encoder(stream, &global));
FOREACH_STREAM(stream, streams) { setup_pass(stream, &global, pass); }
FOREACH_STREAM(stream, streams) {
open_output_file(stream, &global, &input.pixel_aspect_ratio);
}
FOREACH_STREAM(stream, streams) { initialize_encoder(stream, &global); }
#if CONFIG_HIGHBITDEPTH
if (strcmp(global.codec->name, "av1") == 0 ||
......@@ -1920,7 +1930,7 @@ int main(int argc, const char **argv_) {
// Check to see if at least one stream uses 16 bit internal.
// Currently assume that the bit_depths for all streams using
// highbitdepth are the same.
FOREACH_STREAM({
FOREACH_STREAM(stream, streams) {
if (stream->config.use_16bit_internal) {
use_16bit_internal = 1;
}
......@@ -1930,7 +1940,7 @@ int main(int argc, const char **argv_) {
input_shift = (int)stream->config.cfg.g_bit_depth -
stream->config.cfg.g_input_bit_depth;
}
});
};
}
#endif
......@@ -1988,31 +1998,35 @@ int main(int argc, const char **argv_) {
aom_usec_timer_start(&timer);
if (use_16bit_internal) {
assert(frame_to_encode->fmt & AOM_IMG_FMT_HIGHBITDEPTH);
FOREACH_STREAM({
FOREACH_STREAM(stream, streams) {
if (stream->config.use_16bit_internal)
encode_frame(stream, &global,
frame_avail ? frame_to_encode : NULL, frames_in);
else
assert(0);
});
};
} else {
assert((frame_to_encode->fmt & AOM_IMG_FMT_HIGHBITDEPTH) == 0);
FOREACH_STREAM(encode_frame(stream, &global,
frame_avail ? frame_to_encode : NULL,
frames_in));
FOREACH_STREAM(stream, streams) {
encode_frame(stream, &global, frame_avail ? frame_to_encode : NULL,
frames_in);
}
}
#else
aom_usec_timer_start(&timer);
FOREACH_STREAM(encode_frame(stream, &global, frame_avail ? &raw : NULL,
frames_in));
FOREACH_STREAM(stream, streams) {
encode_frame(stream, &global, frame_avail ? &raw : NULL, frames_in);
}
#endif
aom_usec_timer_mark(&timer);
cx_time += aom_usec_timer_elapsed(&timer);
FOREACH_STREAM(update_quantizer_histogram(stream));
FOREACH_STREAM(stream, streams) { update_quantizer_histogram(stream); }
got_data = 0;
FOREACH_STREAM(get_cx_data(stream, &global, &got_data));
FOREACH_STREAM(stream, streams) {
get_cx_data(stream, &global, &got_data);
}
if (!got_data && input.length && streams != NULL &&
!streams->frames_out) {
......@@ -2041,8 +2055,11 @@ int main(int argc, const char **argv_) {
estimated_time_left = average_rate ? remaining / average_rate : -1;
}
if (got_data && global.test_decode != TEST_DECODE_OFF)
FOREACH_STREAM(test_decode(stream, global.test_decode, global.codec));
if (got_data && global.test_decode != TEST_DECODE_OFF) {
FOREACH_STREAM(stream, streams) {
test_decode(stream, global.test_decode, global.codec);
}
}
}
fflush(stdout);
......@@ -2052,68 +2069,84 @@ int main(int argc, const char **argv_) {
if (stream_cnt > 1) fprintf(stderr, "\n");
if (!global.quiet) {
FOREACH_STREAM(fprintf(
stderr, "\rPass %d/%d frame %4d/%-4d %7" PRId64 "B %7" PRId64
"b/f %7" PRId64 "b/s"
" %7" PRId64 " %s (%.2f fps)\033[K\n",
pass + 1, global.passes, frames_in, stream->frames_out,
(int64_t)stream->nbytes,
seen_frames ? (int64_t)(stream->nbytes * 8 / seen_frames) : 0,
seen_frames
? (int64_t)stream->nbytes * 8 * (int64_t)global.framerate.num /
global.framerate.den / seen_frames
: 0,
stream->cx_time > 9999999 ? stream->cx_time / 1000 : stream->cx_time,
stream->cx_time > 9999999 ? "ms" : "us",
usec_to_fps(stream->cx_time, seen_frames)));
FOREACH_STREAM(stream, streams) {
fprintf(stderr, "\rPass %d/%d frame %4d/%-4d %7" PRId64 "B %7" PRId64
"b/f %7" PRId64
"b/s"
" %7" PRId64 " %s (%.2f fps)\033[K\n",
pass + 1, global.passes, frames_in, stream->frames_out,
(int64_t)stream->nbytes,
seen_frames ? (int64_t)(stream->nbytes * 8 / seen_frames) : 0,
seen_frames
? (int64_t)stream->nbytes * 8 *
(int64_t)global.framerate.num / global.framerate.den /
seen_frames
: 0,
stream->cx_time > 9999999 ? stream->cx_time / 1000
: stream->cx_time,
stream->cx_time > 9999999 ? "ms" : "us",
usec_to_fps(stream->cx_time, seen_frames));
}
}
if (global.show_psnr) {
if (global.codec->fourcc == AV1_FOURCC) {
FOREACH_STREAM(
show_psnr(stream, (1 << stream->config.cfg.g_input_bit_depth) - 1));
FOREACH_STREAM(stream, streams) {
show_psnr(stream, (1 << stream->config.cfg.g_input_bit_depth) - 1);
}
} else {
FOREACH_STREAM(show_psnr(stream, 255.0));
FOREACH_STREAM(stream, streams) { show_psnr(stream, 255.0); }
}
}
FOREACH_STREAM(aom_codec_destroy(&stream->encoder));
FOREACH_STREAM(stream, streams) { aom_codec_destroy(&stream->encoder); }
if (global.test_decode != TEST_DECODE_OFF) {
FOREACH_STREAM(aom_codec_destroy(&stream->decoder));
FOREACH_STREAM(stream, streams) { aom_codec_destroy(&stream->decoder); }
}
close_input_file(&input);
if (global.test_decode == TEST_DECODE_FATAL) {
FOREACH_STREAM(res |= stream->mismatch_seen);
FOREACH_STREAM(stream, streams) { res |= stream->mismatch_seen; }
}
FOREACH_STREAM(stream, streams) {
close_output_file(stream, global.codec->fourcc);
}
FOREACH_STREAM(close_output_file(stream, global.codec->fourcc));
FOREACH_STREAM(stats_close(&stream->stats, global.passes - 1));
FOREACH_STREAM(stream, streams) {
stats_close(&stream->stats, global.passes - 1);
}
#if CONFIG_FP_MB_STATS
FOREACH_STREAM(stats_close(&stream->fpmb_stats, global.passes - 1));
FOREACH_STREAM(stream, streams) {
stats_close(&stream->fpmb_stats, global.passes - 1);
}
#endif
if (global.pass) break;
}
if (global.show_q_hist_buckets)
FOREACH_STREAM(
show_q_histogram(stream->counts, global.show_q_hist_buckets));
if (global.show_q_hist_buckets) {
FOREACH_STREAM(stream, streams) {
show_q_histogram(stream->counts, global.show_q_hist_buckets);
}
}
if (global.show_rate_hist_buckets)
FOREACH_STREAM(show_rate_histogram(stream->rate_hist, &stream->config.cfg,
global.show_rate_hist_buckets));
FOREACH_STREAM(destroy_rate_histogram(stream->rate_hist));
if (global.show_rate_hist_buckets) {
FOREACH_STREAM(stream, streams) {
show_rate_histogram(stream->rate_hist, &stream->config.cfg,
global.show_rate_hist_buckets);
}
}
FOREACH_STREAM(stream, streams) { destroy_rate_histogram(stream->rate_hist); }
#if CONFIG_INTERNAL_STATS
/* TODO(jkoleszar): This doesn't belong in this executable. Do it for now,
* to match some existing utilities.
*/
if (!(global.pass == 1 && global.passes == 2))
FOREACH_STREAM({
if (!(global.pass == 1 && global.passes == 2)) {
FOREACH_STREAM(stream, streams) {
FILE *f = fopen("opsnr.stt", "a");
if (stream->mismatch_seen) {
fprintf(f, "First mismatch occurred in frame %d\n",
......@@ -2122,7 +2155,8 @@ int main(int argc, const char **argv_) {
fprintf(f, "No mismatch detected in recon buffers\n");
}
fclose(f);
});
}
}
#endif
#if CONFIG_HIGHBITDEPTH
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment