blob: c2b1644b7c49a66a171eb013c4c606aba7aeb574 [file] [log] [blame]
/*
* Copyright (c) 2017, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 2 Clause License and
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
* was not distributed with this source code in the LICENSE file, you can
* obtain it at www.aomedia.org/license/software. If the Alliance for Open
* Media Patent License 1.0 was not distributed with this source code in the
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
#include <stdlib.h>
#include <string.h>
#include <memory>
#include <string>
#include "./aom_config.h"
#include "./ivfdec.h"
#include "tools/obu_parser.h"
#include "./tools_common.h"
#include "./webmdec.h"
namespace {
const size_t kInitialBufferSize = 100 * 1024;
struct InputContext {
InputContext() = default;
~InputContext() { free(unit_buffer); }
void Init() {
memset(avx_ctx, 0, sizeof(*avx_ctx));
#if CONFIG_WEBM_IO
memset(webm_ctx, 0, sizeof(*webm_ctx));
#endif
}
AvxInputContext *avx_ctx = nullptr;
#if CONFIG_WEBM_IO
WebmInputContext *webm_ctx = nullptr;
#endif
uint8_t *unit_buffer = nullptr;
size_t unit_buffer_size = 0;
};
void PrintUsage() {
printf("Libaom OBU dump.\nUsage: dump_obu <input_file>\n");
}
VideoFileType GetFileType(InputContext *ctx) {
if (file_is_ivf(ctx->avx_ctx)) return FILE_TYPE_IVF;
#if CONFIG_WEBM_IO
if (file_is_webm(ctx->webm_ctx, ctx->avx_ctx)) return FILE_TYPE_WEBM;
#endif
return FILE_TYPE_RAW;
}
bool ReadTemporalUnit(InputContext *ctx, size_t *unit_size) {
const VideoFileType file_type = ctx->avx_ctx->file_type;
switch (file_type) {
case FILE_TYPE_IVF: {
if (ivf_read_frame(ctx->avx_ctx->file, &ctx->unit_buffer, unit_size,
&ctx->unit_buffer_size)) {
return false;
}
break;
}
#if CONFIG_WEBM_IO
case FILE_TYPE_WEBM: {
size_t frame_size = ctx->unit_buffer_size;
if (webm_read_frame(ctx->webm_ctx, &ctx->unit_buffer, &frame_size)) {
return false;
}
if (frame_size != ctx->unit_buffer_size &&
frame_size > ctx->unit_buffer_size) {
// webmdec realloc'd the buffer, store new size.
ctx->unit_buffer_size = frame_size;
}
*unit_size = frame_size;
break;
}
#endif
default:
// TODO(tomfinegan): Abuse FILE_TYPE_RAW for AV1/OBU elementary streams?
fprintf(stderr, "Error: Unsupported file type.\n");
return false;
}
return true;
}
} // namespace
int main(int argc, const char *argv[]) {
// TODO(tomfinegan): Could do with some params for verbosity.
if (argc < 2) {
PrintUsage();
return EXIT_SUCCESS;
}
const std::string filename = argv[1];
using FilePtr = std::unique_ptr<FILE, decltype(&fclose)>;
FilePtr input_file(fopen(filename.c_str(), "rb"), &fclose);
if (input_file.get() == nullptr) {
input_file.release();
fprintf(stderr, "Error: Cannot open input file.\n");
return EXIT_FAILURE;
}
AvxInputContext avx_ctx;
InputContext input_ctx;
input_ctx.avx_ctx = &avx_ctx;
#if CONFIG_WEBM_IO
WebmInputContext webm_ctx;
input_ctx.webm_ctx = &webm_ctx;
#endif
input_ctx.Init();
avx_ctx.file = input_file.get();
avx_ctx.file_type = GetFileType(&input_ctx);
// Note: the reader utilities will realloc the buffer using realloc() etc.
// Can't have nice things like unique_ptr wrappers with that type of
// behavior underneath the function calls.
input_ctx.unit_buffer =
reinterpret_cast<uint8_t *>(calloc(kInitialBufferSize, 1));
if (!input_ctx.unit_buffer) {
fprintf(stderr, "Error: No memory, can't alloc input buffer.\n");
return EXIT_FAILURE;
}
input_ctx.unit_buffer_size = kInitialBufferSize;
size_t unit_size = 0;
int unit_number = 0;
while (ReadTemporalUnit(&input_ctx, &unit_size)) {
printf("Temporal unit %d\n", unit_number);
if (!aom_tools::DumpObu(input_ctx.unit_buffer, unit_size)) {
fprintf(stderr, "Error: Temporal Unit parse failed on unit number %d.\n",
unit_number);
return EXIT_FAILURE;
}
++unit_number;
}
return EXIT_SUCCESS;
}