ivfdec.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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 "common/ivfdec.h"
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include "aom_ports/mem_ops.h"
  16. #include "aom_ports/sanitizer.h"
  17. #include "tools_common.h"
  18. static const char *IVF_SIGNATURE = "DKIF";
  19. static void fix_framerate(int *num, int *den) {
  20. if (*den <= 0 || *den >= 1000000000 || *num <= 0 || *num >= 1000) {
  21. // framerate seems to be invalid, just default to 30fps.
  22. *num = 30;
  23. *den = 1;
  24. }
  25. }
  26. int file_is_ivf(struct AvxInputContext *input_ctx) {
  27. unsigned char raw_hdr[32];
  28. int is_ivf = 0;
  29. if (buffer_input(input_ctx, 32, raw_hdr, /*buffered=*/true) == 32) {
  30. if (memcmp(IVF_SIGNATURE, raw_hdr, 4) == 0) {
  31. is_ivf = 1;
  32. if (mem_get_le16(raw_hdr + 4) != 0) {
  33. fprintf(stderr,
  34. "Error: Unrecognized IVF version! This file may not"
  35. " decode properly.\n");
  36. }
  37. input_ctx->fourcc = mem_get_le32(raw_hdr + 8);
  38. input_ctx->width = mem_get_le16(raw_hdr + 12);
  39. input_ctx->height = mem_get_le16(raw_hdr + 14);
  40. input_ctx->framerate.numerator = mem_get_le32(raw_hdr + 16);
  41. input_ctx->framerate.denominator = mem_get_le32(raw_hdr + 20);
  42. fix_framerate(&input_ctx->framerate.numerator,
  43. &input_ctx->framerate.denominator);
  44. }
  45. }
  46. if (!is_ivf) {
  47. rewind_detect(input_ctx);
  48. }
  49. return is_ivf;
  50. }
  51. int ivf_read_frame(struct AvxInputContext *input_ctx, uint8_t **buffer,
  52. size_t *bytes_read, size_t *buffer_size,
  53. aom_codec_pts_t *pts) {
  54. unsigned char raw_header[IVF_FRAME_HDR_SZ] = { 0 };
  55. size_t frame_size = 0;
  56. if (read_from_input(input_ctx, IVF_FRAME_HDR_SZ, raw_header) !=
  57. IVF_FRAME_HDR_SZ) {
  58. if (!input_eof(input_ctx))
  59. fprintf(stderr, "Warning: Failed to read frame size\n");
  60. } else {
  61. frame_size = mem_get_le32(raw_header);
  62. if (frame_size > 256 * 1024 * 1024) {
  63. fprintf(stderr, "Warning: Read invalid frame size (%u)\n",
  64. (unsigned int)frame_size);
  65. frame_size = 0;
  66. }
  67. if (frame_size > *buffer_size) {
  68. uint8_t *new_buffer = (uint8_t *)realloc(*buffer, 2 * frame_size);
  69. if (new_buffer) {
  70. *buffer = new_buffer;
  71. *buffer_size = 2 * frame_size;
  72. } else {
  73. fprintf(stderr, "Warning: Failed to allocate compressed data buffer\n");
  74. frame_size = 0;
  75. }
  76. }
  77. if (pts) {
  78. *pts = mem_get_le32(&raw_header[4]);
  79. *pts += ((aom_codec_pts_t)mem_get_le32(&raw_header[8]) << 32);
  80. }
  81. }
  82. if (!input_eof(input_ctx)) {
  83. ASAN_UNPOISON_MEMORY_REGION(*buffer, *buffer_size);
  84. if (read_from_input(input_ctx, frame_size, *buffer) != frame_size) {
  85. fprintf(stderr, "Warning: Failed to read full frame\n");
  86. return 1;
  87. }
  88. ASAN_POISON_MEMORY_REGION(*buffer + frame_size, *buffer_size - frame_size);
  89. *bytes_read = frame_size;
  90. return 0;
  91. }
  92. return 1;
  93. }