tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ivfdec.c (3422B)


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