xref: /aosp_15_r20/external/libaom/tools/dump_obu.cc (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker  * Copyright (c) 2017, 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 
12*77c1e3ccSAndroid Build Coastguard Worker #include <stdlib.h>
13*77c1e3ccSAndroid Build Coastguard Worker #include <string.h>
14*77c1e3ccSAndroid Build Coastguard Worker 
15*77c1e3ccSAndroid Build Coastguard Worker #include <memory>
16*77c1e3ccSAndroid Build Coastguard Worker #include <string>
17*77c1e3ccSAndroid Build Coastguard Worker 
18*77c1e3ccSAndroid Build Coastguard Worker #include "config/aom_config.h"
19*77c1e3ccSAndroid Build Coastguard Worker 
20*77c1e3ccSAndroid Build Coastguard Worker #include "common/ivfdec.h"
21*77c1e3ccSAndroid Build Coastguard Worker #include "common/obudec.h"
22*77c1e3ccSAndroid Build Coastguard Worker #include "common/tools_common.h"
23*77c1e3ccSAndroid Build Coastguard Worker #include "common/webmdec.h"
24*77c1e3ccSAndroid Build Coastguard Worker #include "tools/obu_parser.h"
25*77c1e3ccSAndroid Build Coastguard Worker 
26*77c1e3ccSAndroid Build Coastguard Worker namespace {
27*77c1e3ccSAndroid Build Coastguard Worker 
28*77c1e3ccSAndroid Build Coastguard Worker const size_t kInitialBufferSize = 100 * 1024;
29*77c1e3ccSAndroid Build Coastguard Worker 
30*77c1e3ccSAndroid Build Coastguard Worker struct InputContext {
31*77c1e3ccSAndroid Build Coastguard Worker   InputContext() = default;
~InputContext__anond9b6dad90111::InputContext32*77c1e3ccSAndroid Build Coastguard Worker   ~InputContext() { free(unit_buffer); }
33*77c1e3ccSAndroid Build Coastguard Worker 
Init__anond9b6dad90111::InputContext34*77c1e3ccSAndroid Build Coastguard Worker   void Init() {
35*77c1e3ccSAndroid Build Coastguard Worker     memset(avx_ctx, 0, sizeof(*avx_ctx));
36*77c1e3ccSAndroid Build Coastguard Worker     memset(obu_ctx, 0, sizeof(*obu_ctx));
37*77c1e3ccSAndroid Build Coastguard Worker     obu_ctx->avx_ctx = avx_ctx;
38*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_WEBM_IO
39*77c1e3ccSAndroid Build Coastguard Worker     memset(webm_ctx, 0, sizeof(*webm_ctx));
40*77c1e3ccSAndroid Build Coastguard Worker #endif
41*77c1e3ccSAndroid Build Coastguard Worker   }
42*77c1e3ccSAndroid Build Coastguard Worker 
43*77c1e3ccSAndroid Build Coastguard Worker   AvxInputContext *avx_ctx = nullptr;
44*77c1e3ccSAndroid Build Coastguard Worker   ObuDecInputContext *obu_ctx = nullptr;
45*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_WEBM_IO
46*77c1e3ccSAndroid Build Coastguard Worker   WebmInputContext *webm_ctx = nullptr;
47*77c1e3ccSAndroid Build Coastguard Worker #endif
48*77c1e3ccSAndroid Build Coastguard Worker   uint8_t *unit_buffer = nullptr;
49*77c1e3ccSAndroid Build Coastguard Worker   size_t unit_buffer_size = 0;
50*77c1e3ccSAndroid Build Coastguard Worker };
51*77c1e3ccSAndroid Build Coastguard Worker 
PrintUsage()52*77c1e3ccSAndroid Build Coastguard Worker void PrintUsage() {
53*77c1e3ccSAndroid Build Coastguard Worker   printf("Libaom OBU dump.\nUsage: dump_obu <input_file>\n");
54*77c1e3ccSAndroid Build Coastguard Worker }
55*77c1e3ccSAndroid Build Coastguard Worker 
GetFileType(InputContext * ctx)56*77c1e3ccSAndroid Build Coastguard Worker VideoFileType GetFileType(InputContext *ctx) {
57*77c1e3ccSAndroid Build Coastguard Worker   // TODO(https://crbug.com/aomedia/1706): webm type does not support reading
58*77c1e3ccSAndroid Build Coastguard Worker   // from stdin yet, and file_is_webm is not using the detect buffer when
59*77c1e3ccSAndroid Build Coastguard Worker   // determining the type. Therefore it should only be checked when using a file
60*77c1e3ccSAndroid Build Coastguard Worker   // and needs to be checked prior to other types.
61*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_WEBM_IO
62*77c1e3ccSAndroid Build Coastguard Worker   if (file_is_webm(ctx->webm_ctx, ctx->avx_ctx)) return FILE_TYPE_WEBM;
63*77c1e3ccSAndroid Build Coastguard Worker #endif
64*77c1e3ccSAndroid Build Coastguard Worker   if (file_is_ivf(ctx->avx_ctx)) return FILE_TYPE_IVF;
65*77c1e3ccSAndroid Build Coastguard Worker   if (file_is_obu(ctx->obu_ctx)) return FILE_TYPE_OBU;
66*77c1e3ccSAndroid Build Coastguard Worker   return FILE_TYPE_RAW;
67*77c1e3ccSAndroid Build Coastguard Worker }
68*77c1e3ccSAndroid Build Coastguard Worker 
ReadTemporalUnit(InputContext * ctx,size_t * unit_size)69*77c1e3ccSAndroid Build Coastguard Worker bool ReadTemporalUnit(InputContext *ctx, size_t *unit_size) {
70*77c1e3ccSAndroid Build Coastguard Worker   const VideoFileType file_type = ctx->avx_ctx->file_type;
71*77c1e3ccSAndroid Build Coastguard Worker   switch (file_type) {
72*77c1e3ccSAndroid Build Coastguard Worker     case FILE_TYPE_IVF: {
73*77c1e3ccSAndroid Build Coastguard Worker       if (ivf_read_frame(ctx->avx_ctx, &ctx->unit_buffer, unit_size,
74*77c1e3ccSAndroid Build Coastguard Worker                          &ctx->unit_buffer_size, NULL)) {
75*77c1e3ccSAndroid Build Coastguard Worker         return false;
76*77c1e3ccSAndroid Build Coastguard Worker       }
77*77c1e3ccSAndroid Build Coastguard Worker       break;
78*77c1e3ccSAndroid Build Coastguard Worker     }
79*77c1e3ccSAndroid Build Coastguard Worker     case FILE_TYPE_OBU: {
80*77c1e3ccSAndroid Build Coastguard Worker       if (obudec_read_temporal_unit(ctx->obu_ctx, &ctx->unit_buffer, unit_size,
81*77c1e3ccSAndroid Build Coastguard Worker                                     &ctx->unit_buffer_size)) {
82*77c1e3ccSAndroid Build Coastguard Worker         return false;
83*77c1e3ccSAndroid Build Coastguard Worker       }
84*77c1e3ccSAndroid Build Coastguard Worker       break;
85*77c1e3ccSAndroid Build Coastguard Worker     }
86*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_WEBM_IO
87*77c1e3ccSAndroid Build Coastguard Worker     case FILE_TYPE_WEBM: {
88*77c1e3ccSAndroid Build Coastguard Worker       if (webm_read_frame(ctx->webm_ctx, &ctx->unit_buffer, unit_size,
89*77c1e3ccSAndroid Build Coastguard Worker                           &ctx->unit_buffer_size)) {
90*77c1e3ccSAndroid Build Coastguard Worker         return false;
91*77c1e3ccSAndroid Build Coastguard Worker       }
92*77c1e3ccSAndroid Build Coastguard Worker       break;
93*77c1e3ccSAndroid Build Coastguard Worker     }
94*77c1e3ccSAndroid Build Coastguard Worker #endif
95*77c1e3ccSAndroid Build Coastguard Worker     default:
96*77c1e3ccSAndroid Build Coastguard Worker       // TODO(tomfinegan): Abuse FILE_TYPE_RAW for AV1/OBU elementary streams?
97*77c1e3ccSAndroid Build Coastguard Worker       fprintf(stderr, "Error: Unsupported file type.\n");
98*77c1e3ccSAndroid Build Coastguard Worker       return false;
99*77c1e3ccSAndroid Build Coastguard Worker   }
100*77c1e3ccSAndroid Build Coastguard Worker 
101*77c1e3ccSAndroid Build Coastguard Worker   return true;
102*77c1e3ccSAndroid Build Coastguard Worker }
103*77c1e3ccSAndroid Build Coastguard Worker 
CloseFile(FILE * stream)104*77c1e3ccSAndroid Build Coastguard Worker void CloseFile(FILE *stream) { fclose(stream); }
105*77c1e3ccSAndroid Build Coastguard Worker 
106*77c1e3ccSAndroid Build Coastguard Worker }  // namespace
107*77c1e3ccSAndroid Build Coastguard Worker 
main(int argc,const char * argv[])108*77c1e3ccSAndroid Build Coastguard Worker int main(int argc, const char *argv[]) {
109*77c1e3ccSAndroid Build Coastguard Worker   // TODO(tomfinegan): Could do with some params for verbosity.
110*77c1e3ccSAndroid Build Coastguard Worker   if (argc < 2) {
111*77c1e3ccSAndroid Build Coastguard Worker     PrintUsage();
112*77c1e3ccSAndroid Build Coastguard Worker     return EXIT_SUCCESS;
113*77c1e3ccSAndroid Build Coastguard Worker   }
114*77c1e3ccSAndroid Build Coastguard Worker 
115*77c1e3ccSAndroid Build Coastguard Worker   const std::string filename = argv[1];
116*77c1e3ccSAndroid Build Coastguard Worker 
117*77c1e3ccSAndroid Build Coastguard Worker   using FilePtr = std::unique_ptr<FILE, decltype(&CloseFile)>;
118*77c1e3ccSAndroid Build Coastguard Worker   FilePtr input_file(fopen(filename.c_str(), "rb"), &CloseFile);
119*77c1e3ccSAndroid Build Coastguard Worker   if (input_file.get() == nullptr) {
120*77c1e3ccSAndroid Build Coastguard Worker     input_file.release();
121*77c1e3ccSAndroid Build Coastguard Worker     fprintf(stderr, "Error: Cannot open input file.\n");
122*77c1e3ccSAndroid Build Coastguard Worker     return EXIT_FAILURE;
123*77c1e3ccSAndroid Build Coastguard Worker   }
124*77c1e3ccSAndroid Build Coastguard Worker 
125*77c1e3ccSAndroid Build Coastguard Worker   AvxInputContext avx_ctx;
126*77c1e3ccSAndroid Build Coastguard Worker   InputContext input_ctx;
127*77c1e3ccSAndroid Build Coastguard Worker   input_ctx.avx_ctx = &avx_ctx;
128*77c1e3ccSAndroid Build Coastguard Worker   ObuDecInputContext obu_ctx;
129*77c1e3ccSAndroid Build Coastguard Worker   input_ctx.obu_ctx = &obu_ctx;
130*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_WEBM_IO
131*77c1e3ccSAndroid Build Coastguard Worker   WebmInputContext webm_ctx;
132*77c1e3ccSAndroid Build Coastguard Worker   input_ctx.webm_ctx = &webm_ctx;
133*77c1e3ccSAndroid Build Coastguard Worker #endif
134*77c1e3ccSAndroid Build Coastguard Worker 
135*77c1e3ccSAndroid Build Coastguard Worker   input_ctx.Init();
136*77c1e3ccSAndroid Build Coastguard Worker   avx_ctx.file = input_file.get();
137*77c1e3ccSAndroid Build Coastguard Worker   avx_ctx.file_type = GetFileType(&input_ctx);
138*77c1e3ccSAndroid Build Coastguard Worker 
139*77c1e3ccSAndroid Build Coastguard Worker   // Note: the reader utilities will realloc the buffer using realloc() etc.
140*77c1e3ccSAndroid Build Coastguard Worker   // Can't have nice things like unique_ptr wrappers with that type of
141*77c1e3ccSAndroid Build Coastguard Worker   // behavior underneath the function calls.
142*77c1e3ccSAndroid Build Coastguard Worker   input_ctx.unit_buffer =
143*77c1e3ccSAndroid Build Coastguard Worker       reinterpret_cast<uint8_t *>(calloc(kInitialBufferSize, 1));
144*77c1e3ccSAndroid Build Coastguard Worker   if (!input_ctx.unit_buffer) {
145*77c1e3ccSAndroid Build Coastguard Worker     fprintf(stderr, "Error: No memory, can't alloc input buffer.\n");
146*77c1e3ccSAndroid Build Coastguard Worker     return EXIT_FAILURE;
147*77c1e3ccSAndroid Build Coastguard Worker   }
148*77c1e3ccSAndroid Build Coastguard Worker   input_ctx.unit_buffer_size = kInitialBufferSize;
149*77c1e3ccSAndroid Build Coastguard Worker 
150*77c1e3ccSAndroid Build Coastguard Worker   size_t unit_size = 0;
151*77c1e3ccSAndroid Build Coastguard Worker   int unit_number = 0;
152*77c1e3ccSAndroid Build Coastguard Worker   int64_t obu_overhead_bytes_total = 0;
153*77c1e3ccSAndroid Build Coastguard Worker   while (ReadTemporalUnit(&input_ctx, &unit_size)) {
154*77c1e3ccSAndroid Build Coastguard Worker     printf("Temporal unit %d\n", unit_number);
155*77c1e3ccSAndroid Build Coastguard Worker 
156*77c1e3ccSAndroid Build Coastguard Worker     int obu_overhead_current_unit = 0;
157*77c1e3ccSAndroid Build Coastguard Worker     if (!aom_tools::DumpObu(input_ctx.unit_buffer, static_cast<int>(unit_size),
158*77c1e3ccSAndroid Build Coastguard Worker                             &obu_overhead_current_unit)) {
159*77c1e3ccSAndroid Build Coastguard Worker       fprintf(stderr, "Error: Temporal Unit parse failed on unit number %d.\n",
160*77c1e3ccSAndroid Build Coastguard Worker               unit_number);
161*77c1e3ccSAndroid Build Coastguard Worker       return EXIT_FAILURE;
162*77c1e3ccSAndroid Build Coastguard Worker     }
163*77c1e3ccSAndroid Build Coastguard Worker     printf("  OBU overhead:    %d\n", obu_overhead_current_unit);
164*77c1e3ccSAndroid Build Coastguard Worker     ++unit_number;
165*77c1e3ccSAndroid Build Coastguard Worker     obu_overhead_bytes_total += obu_overhead_current_unit;
166*77c1e3ccSAndroid Build Coastguard Worker   }
167*77c1e3ccSAndroid Build Coastguard Worker 
168*77c1e3ccSAndroid Build Coastguard Worker   printf("File total OBU overhead: %" PRId64 "\n", obu_overhead_bytes_total);
169*77c1e3ccSAndroid Build Coastguard Worker   return EXIT_SUCCESS;
170*77c1e3ccSAndroid Build Coastguard Worker }
171