blob: 078be62cfeb578b49db1ea162ba0586a2a0eaa5b [file] [log] [blame] [edit]
/*
* Copyright (c) 2021, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 3-Clause Clear License
* and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
* License was not distributed with this source code in the LICENSE file, you
* can obtain it at aomedia.org/license/software-license/bsd-3-c-c/. If the
* Alliance for Open Media Patent License 1.0 was not distributed with this
* source code in the PATENTS file, you can obtain it at
* aomedia.org/license/patent-license/.
*/
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include "common/stream_iter.h"
#include "common/y4minput.h"
static int copy_reader(StreamIter *iter, aom_image_t *img) {
struct AvxInputContext *input_ctx = iter->input.avx;
FILE *f = input_ctx->file;
y4m_input *y4m = &input_ctx->y4m;
int shortread = 0;
if (input_ctx->file_type == FILE_TYPE_Y4M) {
if (y4m_input_fetch_frame(y4m, f, img) < 1) return 0;
} else {
shortread = read_yuv_frame(input_ctx, img);
}
return !shortread;
}
void copy_stream_iter_init(StreamIter *iter, struct AvxInputContext *input) {
iter->input.avx = input;
iter->reader = copy_reader;
}
static int skip_reader(StreamIter *iter, aom_image_t *raw) {
// While we haven't skipped enough frames, read from the underlying
// stream and throw the result away. If no frame is available, early
// exit.
while (iter->current < iter->n) {
++iter->current;
int frame_avail = read_stream_iter(iter->input.stream, raw);
if (!frame_avail) {
return frame_avail;
}
}
// If we're past the skip region, copy the remaining output.
return read_stream_iter(iter->input.stream, raw);
}
void skip_stream_iter_init(StreamIter *iter, StreamIter *input, int num_skip) {
assert(num_skip >= 0);
iter->input.stream = input;
iter->current = 0;
iter->n = num_skip;
iter->reader = skip_reader;
}
static int step_reader(StreamIter *iter, aom_image_t *raw) {
while (true) {
int frame_avail = read_stream_iter(iter->input.stream, raw);
// If at end of stream, no need to read further.
if (!frame_avail) {
return frame_avail;
}
bool should_encode = iter->current == 0;
iter->current = (iter->current + 1) % (iter->n);
if (should_encode) {
return frame_avail;
}
}
}
void step_stream_iter_init(StreamIter *iter, StreamIter *input, int step_size) {
assert(step_size > 0);
iter->input.stream = input;
iter->current = 0;
iter->n = step_size;
iter->reader = step_reader;
}
static int limit_reader(StreamIter *iter, aom_image_t *raw) {
// limit of 0 is a special case meaning "no limit".
if (iter->n != 0 && iter->current >= iter->n) {
return 0;
}
++iter->current;
return read_stream_iter(iter->input.stream, raw);
}
void limit_stream_iter_init(StreamIter *iter, StreamIter *input, int limit) {
assert(limit >= 0);
iter->input.stream = input;
iter->current = 0;
iter->n = limit;
iter->reader = limit_reader;
}
int read_stream_iter(StreamIter *iter, aom_image_t *raw) {
return iter->reader(iter, raw);
}