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