blob: cb33cfbbb60dc53aad413d3ec7c667cb609174f6 [file] [log] [blame]
Tom Fineganc0192332017-12-02 09:31:45 -08001/*
2 * Copyright (c) 2017, 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
12#include <stdlib.h>
13#include <string.h>
14
15#include <memory>
16#include <string>
17
18#include "./aom_config.h"
19#include "./ivfdec.h"
20#include "tools/obu_parser.h"
21#include "./tools_common.h"
22#include "./webmdec.h"
23
24namespace {
25
26const size_t kInitialBufferSize = 100 * 1024;
27
28struct InputContext {
29 InputContext() = default;
30 ~InputContext() { free(unit_buffer); }
31
32 void Init() {
33 memset(avx_ctx, 0, sizeof(*avx_ctx));
34#if CONFIG_WEBM_IO
35 memset(webm_ctx, 0, sizeof(*webm_ctx));
36#endif
37 }
38
39 AvxInputContext *avx_ctx = nullptr;
40#if CONFIG_WEBM_IO
41 WebmInputContext *webm_ctx = nullptr;
42#endif
43 uint8_t *unit_buffer = nullptr;
44 size_t unit_buffer_size = 0;
45};
46
47void PrintUsage() {
48 printf("Libaom OBU dump.\nUsage: dump_obu <input_file>\n");
49}
50
51VideoFileType GetFileType(InputContext *ctx) {
52 if (file_is_ivf(ctx->avx_ctx)) return FILE_TYPE_IVF;
53#if CONFIG_WEBM_IO
54 if (file_is_webm(ctx->webm_ctx, ctx->avx_ctx)) return FILE_TYPE_WEBM;
55#endif
56 return FILE_TYPE_RAW;
57}
58
59bool ReadTemporalUnit(InputContext *ctx, size_t *unit_size) {
60 const VideoFileType file_type = ctx->avx_ctx->file_type;
61 switch (file_type) {
62 case FILE_TYPE_IVF: {
63 if (ivf_read_frame(ctx->avx_ctx->file, &ctx->unit_buffer, unit_size,
64 &ctx->unit_buffer_size)) {
65 return false;
66 }
67 break;
68 }
69#if CONFIG_WEBM_IO
70 case FILE_TYPE_WEBM: {
71 size_t frame_size = ctx->unit_buffer_size;
72 if (webm_read_frame(ctx->webm_ctx, &ctx->unit_buffer, &frame_size)) {
73 return false;
74 }
75
76 if (frame_size != ctx->unit_buffer_size &&
77 frame_size > ctx->unit_buffer_size) {
78 // webmdec realloc'd the buffer, store new size.
79 ctx->unit_buffer_size = frame_size;
80 }
81
82 *unit_size = frame_size;
83 break;
84 }
85#endif
86 default:
87 // TODO(tomfinegan): Abuse FILE_TYPE_RAW for AV1/OBU elementary streams?
88 fprintf(stderr, "Error: Unsupported file type.\n");
89 return false;
90 }
91
92 return true;
93}
94
95} // namespace
96
97int main(int argc, const char *argv[]) {
98 // TODO(tomfinegan): Could do with some params for verbosity.
99 if (argc < 2) {
100 PrintUsage();
101 return EXIT_SUCCESS;
102 }
103
104 const std::string filename = argv[1];
105
106 using FilePtr = std::unique_ptr<FILE, decltype(&fclose)>;
107 FilePtr input_file(fopen(filename.c_str(), "rb"), &fclose);
108 if (input_file.get() == nullptr) {
109 input_file.release();
110 fprintf(stderr, "Error: Cannot open input file.\n");
111 return EXIT_FAILURE;
112 }
113
114 AvxInputContext avx_ctx;
115 InputContext input_ctx;
116 input_ctx.avx_ctx = &avx_ctx;
117#if CONFIG_WEBM_IO
118 WebmInputContext webm_ctx;
119 input_ctx.webm_ctx = &webm_ctx;
120#endif
121
122 input_ctx.Init();
123 avx_ctx.file = input_file.get();
124 avx_ctx.file_type = GetFileType(&input_ctx);
125
126 // Note: the reader utilities will realloc the buffer using realloc() etc.
127 // Can't have nice things like unique_ptr wrappers with that type of
128 // behavior underneath the function calls.
129 input_ctx.unit_buffer =
130 reinterpret_cast<uint8_t *>(calloc(kInitialBufferSize, 1));
131 if (!input_ctx.unit_buffer) {
132 fprintf(stderr, "Error: No memory, can't alloc input buffer.\n");
133 return EXIT_FAILURE;
134 }
135 input_ctx.unit_buffer_size = kInitialBufferSize;
136
137 size_t unit_size = 0;
138 int unit_number = 0;
Tom Finegana6f987b2018-02-07 10:02:53 -0800139 int64_t obu_overhead_bytes_total = 0;
Tom Fineganc0192332017-12-02 09:31:45 -0800140 while (ReadTemporalUnit(&input_ctx, &unit_size)) {
141 printf("Temporal unit %d\n", unit_number);
Tom Finegana6f987b2018-02-07 10:02:53 -0800142
143 int obu_overhead_current_unit = 0;
144 if (!aom_tools::DumpObu(input_ctx.unit_buffer, static_cast<int>(unit_size),
145 &obu_overhead_current_unit)) {
Tom Fineganc0192332017-12-02 09:31:45 -0800146 fprintf(stderr, "Error: Temporal Unit parse failed on unit number %d.\n",
147 unit_number);
148 return EXIT_FAILURE;
149 }
Tom Finegana6f987b2018-02-07 10:02:53 -0800150 printf(" OBU overhead: %d\n", obu_overhead_current_unit);
Tom Fineganc0192332017-12-02 09:31:45 -0800151 ++unit_number;
Tom Finegana6f987b2018-02-07 10:02:53 -0800152 obu_overhead_bytes_total += obu_overhead_current_unit;
Tom Fineganc0192332017-12-02 09:31:45 -0800153 }
154
Tom Finegana6f987b2018-02-07 10:02:53 -0800155 printf("File total OBU overhead: %" PRId64 "\n", obu_overhead_bytes_total);
Tom Fineganc0192332017-12-02 09:31:45 -0800156 return EXIT_SUCCESS;
157}