video_reader.c (4513B)
1 /* 2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved. 3 * 4 * This source code is subject to the terms of the BSD 2 Clause License and 5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License 6 * was not distributed with this source code in the LICENSE file, you can 7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open 8 * Media Patent License 1.0 was not distributed with this source code in the 9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent. 10 */ 11 #include <stdlib.h> 12 #include <string.h> 13 #include <assert.h> 14 15 #include "aom_ports/mem_ops.h" 16 #include "common/ivfdec.h" 17 #include "common/obudec.h" 18 #include "common/tools_common.h" 19 #include "common/video_reader.h" 20 #include "common/webmdec.h" 21 22 struct AvxVideoReaderStruct { 23 AvxVideoInfo info; 24 struct AvxInputContext input_ctx; 25 struct ObuDecInputContext obu_ctx; 26 struct WebmInputContext webm_ctx; 27 uint8_t *buffer; 28 size_t buffer_size; 29 size_t frame_size; 30 aom_codec_pts_t pts; 31 }; 32 33 AvxVideoReader *aom_video_reader_open(const char *filename) { 34 AvxVideoReader *reader = NULL; 35 const bool using_file = strcmp(filename, "-") != 0; 36 FILE *const file = 37 using_file ? fopen(filename, "rb") : set_binary_mode(stdin); 38 if (!file) return NULL; // Can't open file 39 40 reader = (AvxVideoReader *)calloc(1, sizeof(*reader)); 41 if (!reader) { 42 fclose(file); 43 return NULL; // Can't allocate AvxVideoReader 44 } 45 46 reader->input_ctx.filename = filename; 47 reader->input_ctx.file = file; 48 reader->obu_ctx.avx_ctx = &reader->input_ctx; 49 reader->obu_ctx.is_annexb = 1; 50 51 // TODO(https://crbug.com/aomedia/1706): webm type does not support reading 52 // from stdin yet, and file_is_webm is not using the detect buffer when 53 // determining the type. Therefore it should only be checked when using a file 54 // and needs to be checked prior to other types. 55 if (false) { 56 #if CONFIG_WEBM_IO 57 } else if (using_file && 58 file_is_webm(&reader->webm_ctx, &reader->input_ctx)) { 59 reader->input_ctx.file_type = FILE_TYPE_WEBM; 60 reader->info.codec_fourcc = reader->input_ctx.fourcc; 61 reader->info.frame_width = reader->input_ctx.width; 62 reader->info.frame_height = reader->input_ctx.height; 63 #endif 64 } else if (file_is_ivf(&reader->input_ctx)) { 65 reader->input_ctx.file_type = FILE_TYPE_IVF; 66 reader->info.codec_fourcc = reader->input_ctx.fourcc; 67 reader->info.frame_width = reader->input_ctx.width; 68 reader->info.frame_height = reader->input_ctx.height; 69 } else if (file_is_obu(&reader->obu_ctx)) { 70 reader->input_ctx.file_type = FILE_TYPE_OBU; 71 // assume AV1 72 reader->info.codec_fourcc = AV1_FOURCC; 73 reader->info.is_annexb = reader->obu_ctx.is_annexb; 74 } else { 75 fclose(file); 76 free(reader); 77 return NULL; // Unknown file type 78 } 79 80 return reader; 81 } 82 83 void aom_video_reader_close(AvxVideoReader *reader) { 84 if (reader) { 85 fclose(reader->input_ctx.file); 86 if (reader->input_ctx.file_type == FILE_TYPE_OBU) { 87 obudec_free(&reader->obu_ctx); 88 } 89 free(reader->buffer); 90 free(reader); 91 } 92 } 93 94 int aom_video_reader_read_frame(AvxVideoReader *reader) { 95 if (reader->input_ctx.file_type == FILE_TYPE_IVF) { 96 return !ivf_read_frame(&reader->input_ctx, &reader->buffer, 97 &reader->frame_size, &reader->buffer_size, 98 &reader->pts); 99 } else if (reader->input_ctx.file_type == FILE_TYPE_OBU) { 100 return !obudec_read_temporal_unit(&reader->obu_ctx, &reader->buffer, 101 &reader->frame_size, 102 &reader->buffer_size); 103 #if CONFIG_WEBM_IO 104 } else if (reader->input_ctx.file_type == FILE_TYPE_WEBM) { 105 return !webm_read_frame(&reader->webm_ctx, &reader->buffer, 106 &reader->frame_size, &reader->buffer_size); 107 #endif 108 } else { 109 assert(0); 110 return 0; 111 } 112 } 113 114 const uint8_t *aom_video_reader_get_frame(AvxVideoReader *reader, 115 size_t *size) { 116 if (size) *size = reader->frame_size; 117 118 return reader->buffer; 119 } 120 121 int64_t aom_video_reader_get_frame_pts(AvxVideoReader *reader) { 122 return (int64_t)reader->pts; 123 } 124 125 FILE *aom_video_reader_get_file(AvxVideoReader *reader) { 126 return reader->input_ctx.file; 127 } 128 129 const AvxVideoInfo *aom_video_reader_get_info(AvxVideoReader *reader) { 130 return &reader->info; 131 } 132 133 void aom_video_reader_set_fourcc(AvxVideoReader *reader, uint32_t fourcc) { 134 reader->info.codec_fourcc = fourcc; 135 }