|  | /* | 
|  | * 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; | 
|  | const bool using_file = strcmp(filename, "-") != 0; | 
|  | FILE *const file = | 
|  | using_file ? fopen(filename, "rb") : set_binary_mode(stdin); | 
|  | 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; | 
|  |  | 
|  | // TODO(https://crbug.com/aomedia/1706): webm type does not support reading | 
|  | // from stdin yet, and file_is_webm is not using the detect buffer when | 
|  | // determining the type. Therefore it should only be checked when using a file | 
|  | // and needs to be checked prior to other types. | 
|  | if (false) { | 
|  | #if CONFIG_WEBM_IO | 
|  | } else if (using_file && | 
|  | 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_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; | 
|  | } 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, &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; | 
|  | } | 
|  |  | 
|  | void aom_video_reader_set_fourcc(AvxVideoReader *reader, uint32_t fourcc) { | 
|  | reader->info.codec_fourcc = fourcc; | 
|  | } |