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 
aom_video_reader_open(const char * filename)33 AvxVideoReader *aom_video_reader_open(const char *filename) {
34   AvxVideoReader *reader = NULL;
35   FILE *const file = fopen(filename, "rb");
36   if (!file) return NULL;  // Can't open file
37 
38   reader = (AvxVideoReader *)calloc(1, sizeof(*reader));
39   if (!reader) {
40     fclose(file);
41     return NULL;  // Can't allocate AvxVideoReader
42   }
43 
44   reader->input_ctx.filename = filename;
45   reader->input_ctx.file = file;
46   reader->obu_ctx.avx_ctx = &reader->input_ctx;
47   reader->obu_ctx.is_annexb = 1;
48 
49   if (file_is_ivf(&reader->input_ctx)) {
50     reader->input_ctx.file_type = FILE_TYPE_IVF;
51     reader->info.codec_fourcc = reader->input_ctx.fourcc;
52     reader->info.frame_width = reader->input_ctx.width;
53     reader->info.frame_height = reader->input_ctx.height;
54 #if CONFIG_WEBM_IO
55   } else if (file_is_webm(&reader->webm_ctx, &reader->input_ctx)) {
56     reader->input_ctx.file_type = FILE_TYPE_WEBM;
57     reader->info.codec_fourcc = reader->input_ctx.fourcc;
58     reader->info.frame_width = reader->input_ctx.width;
59     reader->info.frame_height = reader->input_ctx.height;
60 #endif
61   } else if (file_is_obu(&reader->obu_ctx)) {
62     reader->input_ctx.file_type = FILE_TYPE_OBU;
63     // assume AV1
64     reader->info.codec_fourcc = AV1_FOURCC;
65     reader->info.is_annexb = reader->obu_ctx.is_annexb;
66   } else {
67     fclose(file);
68     free(reader);
69     return NULL;  // Unknown file type
70   }
71 
72   return reader;
73 }
74 
aom_video_reader_close(AvxVideoReader * reader)75 void aom_video_reader_close(AvxVideoReader *reader) {
76   if (reader) {
77     fclose(reader->input_ctx.file);
78     if (reader->input_ctx.file_type == FILE_TYPE_OBU) {
79       obudec_free(&reader->obu_ctx);
80     }
81     free(reader->buffer);
82     free(reader);
83   }
84 }
85 
aom_video_reader_read_frame(AvxVideoReader * reader)86 int aom_video_reader_read_frame(AvxVideoReader *reader) {
87   if (reader->input_ctx.file_type == FILE_TYPE_IVF) {
88     return !ivf_read_frame(reader->input_ctx.file, &reader->buffer,
89                            &reader->frame_size, &reader->buffer_size,
90                            &reader->pts);
91   } else if (reader->input_ctx.file_type == FILE_TYPE_OBU) {
92     return !obudec_read_temporal_unit(&reader->obu_ctx, &reader->buffer,
93                                       &reader->frame_size,
94                                       &reader->buffer_size);
95 #if CONFIG_WEBM_IO
96   } else if (reader->input_ctx.file_type == FILE_TYPE_WEBM) {
97     return !webm_read_frame(&reader->webm_ctx, &reader->buffer,
98                             &reader->frame_size, &reader->buffer_size);
99 #endif
100   } else {
101     assert(0);
102     return 0;
103   }
104 }
105 
aom_video_reader_get_frame(AvxVideoReader * reader,size_t * size)106 const uint8_t *aom_video_reader_get_frame(AvxVideoReader *reader,
107                                           size_t *size) {
108   if (size) *size = reader->frame_size;
109 
110   return reader->buffer;
111 }
112 
aom_video_reader_get_frame_pts(AvxVideoReader * reader)113 int64_t aom_video_reader_get_frame_pts(AvxVideoReader *reader) {
114   return (int64_t)reader->pts;
115 }
116 
aom_video_reader_get_file(AvxVideoReader * reader)117 FILE *aom_video_reader_get_file(AvxVideoReader *reader) {
118   return reader->input_ctx.file;
119 }
120 
aom_video_reader_get_info(AvxVideoReader * reader)121 const AvxVideoInfo *aom_video_reader_get_info(AvxVideoReader *reader) {
122   return &reader->info;
123 }
124