| /* | 
 |  * 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; | 
 | } |