/* * Copyright (c) 2016, Alliance for Open Media. All rights reserved * * This source code is subject to the terms of the BSD 2 Clause License and * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License * was not distributed with this source code in the LICENSE file, you can * obtain it at www.aomedia.org/license/software. 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 www.aomedia.org/license/patent. */ #include <stdlib.h> #include <string.h> #include <assert.h> #include "aom_ports/mem_ops.h" #include "common/ivfdec.h" #include "common/obudec.h" #include "common/tools_common.h" #include "common/video_reader.h" #include "common/webmdec.h" struct AvxVideoReaderStruct { AvxVideoInfo info; struct AvxInputContext input_ctx; struct ObuDecInputContext obu_ctx; struct WebmInputContext webm_ctx; uint8_t *buffer; size_t buffer_size; size_t frame_size; aom_codec_pts_t pts; }; AvxVideoReader *aom_video_reader_open(const char *filename) { AvxVideoReader *reader = NULL; FILE *const file = fopen(filename, "rb"); if (!file) return NULL; // Can't open file reader = (AvxVideoReader *)calloc(1, sizeof(*reader)); if (!reader) { fclose(file); return NULL; // Can't allocate AvxVideoReader } reader->input_ctx.filename = filename; reader->input_ctx.file = file; reader->obu_ctx.avx_ctx = &reader->input_ctx; reader->obu_ctx.is_annexb = 1; if (file_is_ivf(&reader->input_ctx)) { reader->input_ctx.file_type = FILE_TYPE_IVF; reader->info.codec_fourcc = reader->input_ctx.fourcc; reader->info.frame_width = reader->input_ctx.width; reader->info.frame_height = reader->input_ctx.height; #if CONFIG_WEBM_IO } else if (file_is_webm(&reader->webm_ctx, &reader->input_ctx)) { reader->input_ctx.file_type = FILE_TYPE_WEBM; reader->info.codec_fourcc = reader->input_ctx.fourcc; reader->info.frame_width = reader->input_ctx.width; reader->info.frame_height = reader->input_ctx.height; #endif } else if (file_is_obu(&reader->obu_ctx)) { reader->input_ctx.file_type = FILE_TYPE_OBU; // assume AV1 reader->info.codec_fourcc = AV1_FOURCC; reader->info.is_annexb = reader->obu_ctx.is_annexb; } else { fclose(file); free(reader); return NULL; // Unknown file type } return reader; } void aom_video_reader_close(AvxVideoReader *reader) { if (reader) { fclose(reader->input_ctx.file); if (reader->input_ctx.file_type == FILE_TYPE_OBU) { obudec_free(&reader->obu_ctx); } free(reader->buffer); free(reader); } } int aom_video_reader_read_frame(AvxVideoReader *reader) { if (reader->input_ctx.file_type == FILE_TYPE_IVF) { return !ivf_read_frame(reader->input_ctx.file, &reader->buffer, &reader->frame_size, &reader->buffer_size, &reader->pts); } else if (reader->input_ctx.file_type == FILE_TYPE_OBU) { return !obudec_read_temporal_unit(&reader->obu_ctx, &reader->buffer, &reader->frame_size, &reader->buffer_size); #if CONFIG_WEBM_IO } else if (reader->input_ctx.file_type == FILE_TYPE_WEBM) { return !webm_read_frame(&reader->webm_ctx, &reader->buffer, &reader->frame_size, &reader->buffer_size); #endif } else { assert(0); return 0; } } const uint8_t *aom_video_reader_get_frame(AvxVideoReader *reader, size_t *size) { if (size) *size = reader->frame_size; return reader->buffer; } int64_t aom_video_reader_get_frame_pts(AvxVideoReader *reader) { return (int64_t)reader->pts; } FILE *aom_video_reader_get_file(AvxVideoReader *reader) { return reader->input_ctx.file; } const AvxVideoInfo *aom_video_reader_get_info(AvxVideoReader *reader) { return &reader->info; }