obudec.c 14.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * 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 <stdio.h>
#include <stdlib.h>
#include <string.h>

Tom Finegan's avatar
Tom Finegan committed
16
#include "common/obudec.h"
17 18 19

#include "aom_ports/mem_ops.h"
#include "av1/common/common.h"
20
#include "av1/decoder/obu.h"
21

22
#define OBU_BUFFER_SIZE (500 * 1024)
23

24 25
#define OBU_HEADER_SIZE 1
#define OBU_EXTENSION_SIZE 1
26
#define OBU_MAX_LENGTH_FIELD_SIZE 8
27
#define OBU_DETECTION_SIZE \
28
  (OBU_HEADER_SIZE + OBU_EXTENSION_SIZE + 3 * OBU_MAX_LENGTH_FIELD_SIZE)
29

30 31 32 33
// Reads unsigned LEB128 integer and returns 0 upon successful read and decode.
// Stores raw bytes in 'value_buffer', length of the number in 'value_length',
// and decoded value in 'value'.
static int obudec_read_leb128(FILE *f, uint8_t *value_buffer,
34
                              size_t *value_length, uint64_t *value) {
35
  if (!f || !value_buffer || !value_length || !value) return -1;
36
  size_t len;
37
  for (len = 0; len < OBU_MAX_LENGTH_FIELD_SIZE; ++len) {
38
    const size_t num_read = fread(&value_buffer[len], 1, 1, f);
39 40 41 42 43
    if (num_read == 0) {
      if (len == 0 && feof(f)) {
        *value_length = 0;
        return 0;
      }
44 45 46
      // Ran out of data before completing read of value.
      return -1;
    }
47
    if ((value_buffer[len] >> 7) == 0) {
48
      ++len;
49
      *value_length = len;
50 51 52 53
      break;
    }
  }

54
  return aom_uleb_decode(value_buffer, len, value, NULL);
55 56 57 58 59 60 61 62 63
}

// Reads OBU header from 'f'. The 'buffer_capacity' passed in must be large
// enough to store an OBU header with extension (2 bytes). Raw OBU data is
// written to 'obu_data', parsed OBU header values are written to 'obu_header',
// and total bytes read from file are written to 'bytes_read'. Returns 0 for
// success, and non-zero on failure. When end of file is reached, the return
// value is 0 and the 'bytes_read' value is set to 0.
static int obudec_read_obu_header(FILE *f, size_t buffer_capacity,
64
                                  int is_annexb, uint8_t *obu_data,
65
                                  ObuHeader *obu_header, size_t *bytes_read) {
66
  if (!f || buffer_capacity < (OBU_HEADER_SIZE + OBU_EXTENSION_SIZE) ||
67
      !obu_data || !obu_header || !bytes_read) {
68
    return -1;
69
  }
70
  *bytes_read = fread(obu_data, 1, 1, f);
71

72 73 74 75 76 77
  if (feof(f) && *bytes_read == 0) {
    return 0;
  } else if (*bytes_read != 1) {
    fprintf(stderr, "obudec: Failure reading OBU header.\n");
    return -1;
  }
78

79
  const int has_extension = (obu_data[0] >> 2) & 0x1;
80 81 82 83
  if (has_extension) {
    if (fread(&obu_data[1], 1, 1, f) != 1) {
      fprintf(stderr, "obudec: Failure reading OBU extension.");
      return -1;
84
    }
85 86
    ++*bytes_read;
  }
87

88
  size_t obu_bytes_parsed = 0;
89 90
  const aom_codec_err_t parse_result = aom_read_obu_header(
      obu_data, *bytes_read, &obu_bytes_parsed, obu_header, is_annexb);
91 92 93 94
  if (parse_result != AOM_CODEC_OK || *bytes_read != obu_bytes_parsed) {
    fprintf(stderr, "obudec: Error parsing OBU header.\n");
    return -1;
  }
95

96 97
  return 0;
}
98

99 100
// Reads OBU payload from 'f' and returns 0 for success when all payload bytes
// are read from the file. Payload data is written to 'obu_data', and actual
101 102 103
// bytes read added to 'bytes_read'.
static int obudec_read_obu_payload(FILE *f, size_t payload_length,
                                   uint8_t *obu_data, size_t *bytes_read) {
104
  if (!f || payload_length == 0 || !obu_data || !bytes_read) return -1;
105

106
  if (fread(obu_data, 1, payload_length, f) != payload_length) {
107 108
    fprintf(stderr, "obudec: Failure reading OBU payload.\n");
    return -1;
109
  }
110

111
  *bytes_read += payload_length;
112 113 114
  return 0;
}

115 116
static int obudec_read_obu_header_and_size(FILE *f, size_t buffer_capacity,
                                           int is_annexb, uint8_t *buffer,
117 118
                                           size_t *bytes_read,
                                           size_t *payload_length,
119 120 121 122
                                           ObuHeader *obu_header) {
  const size_t kMinimumBufferSize =
      (OBU_HEADER_SIZE + OBU_EXTENSION_SIZE + OBU_MAX_LENGTH_FIELD_SIZE);
  if (!f || !buffer || !bytes_read || !payload_length || !obu_header ||
123 124 125
      buffer_capacity < kMinimumBufferSize) {
    return -1;
  }
126

127
  size_t leb128_length = 0;
128 129
  uint64_t obu_size = 0;
  if (is_annexb) {
130
    if (obudec_read_leb128(f, &buffer[0], &leb128_length, &obu_size) != 0) {
131 132 133
      fprintf(stderr, "obudec: Failure reading OBU size length.\n");
      return -1;
    } else if (leb128_length == 0) {
134
      *payload_length = 0;
135 136
      return 0;
    }
137 138 139 140
    if (obu_size > UINT32_MAX) {
      fprintf(stderr, "obudec: OBU payload length too large.\n");
      return -1;
    }
141 142
  }

143
  size_t header_size = 0;
144
  if (obudec_read_obu_header(f, buffer_capacity - leb128_length, is_annexb,
145 146
                             buffer + leb128_length, obu_header,
                             &header_size) != 0) {
147
    return -1;
148 149
  } else if (header_size == 0) {
    *payload_length = 0;
150 151
    return 0;
  }
Tom Finegan's avatar
Tom Finegan committed
152

153 154 155 156 157
  if (is_annexb) {
    if (obu_size < header_size) {
      fprintf(stderr, "obudec: OBU size is too small.\n");
      return -1;
    }
158
    *payload_length = (size_t)obu_size - header_size;
159
  } else {
160
    uint64_t u64_payload_length = 0;
161
    if (obudec_read_leb128(f, &buffer[header_size], &leb128_length,
162
                           &u64_payload_length) != 0) {
163 164 165
      fprintf(stderr, "obudec: Failure reading OBU payload length.\n");
      return -1;
    }
166 167 168 169 170 171
    if (u64_payload_length > UINT32_MAX) {
      fprintf(stderr, "obudec: OBU payload length too large.\n");
      return -1;
    }

    *payload_length = (size_t)u64_payload_length;
172
  }
173

174 175 176 177
  *bytes_read = leb128_length + header_size;
  return 0;
}

178 179
static int obudec_read_one_obu(FILE *f, uint8_t **obu_buffer,
                               size_t obu_bytes_buffered,
180 181 182
                               size_t *obu_buffer_capacity, size_t *obu_length,
                               ObuHeader *obu_header, int is_annexb) {
  size_t available_buffer_capacity = *obu_buffer_capacity - obu_bytes_buffered;
183 184

  if (!(*obu_buffer)) return -1;
185

186 187
  size_t bytes_read = 0;
  size_t obu_payload_length = 0;
188
  const int status = obudec_read_obu_header_and_size(
189 190
      f, available_buffer_capacity, is_annexb, *obu_buffer + obu_bytes_buffered,
      &bytes_read, &obu_payload_length, obu_header);
191
  if (status < 0) return status;
192

193
  if (obu_payload_length > SIZE_MAX - bytes_read) return -1;
194 195

  if (obu_payload_length > 256 * 1024 * 1024) {
196 197
    fprintf(stderr, "obudec: Read invalid OBU size (%u)\n",
            (unsigned int)obu_payload_length);
198 199 200
    *obu_length = bytes_read + obu_payload_length;
    return -1;
  }
Tom Finegan's avatar
Tom Finegan committed
201

202
  if (bytes_read + obu_payload_length > available_buffer_capacity) {
203 204
    // TODO(tomfinegan): Add overflow check.
    const size_t new_capacity =
205
        obu_bytes_buffered + bytes_read + 2 * obu_payload_length;
206 207 208 209 210 211 212 213

#if defined AOM_MAX_ALLOCABLE_MEMORY
    if (new_capacity > AOM_MAX_ALLOCABLE_MEMORY) {
      fprintf(stderr, "obudec: OBU size exceeds max alloc size.\n");
      return -1;
    }
#endif

214 215 216 217 218 219
    uint8_t *new_buffer = (uint8_t *)realloc(*obu_buffer, new_capacity);

    if (new_buffer) {
      *obu_buffer = new_buffer;
      *obu_buffer_capacity = new_capacity;
    } else {
220
      fprintf(stderr, "obudec: Failed to allocate compressed data buffer\n");
221 222 223 224 225
      *obu_length = bytes_read + obu_payload_length;
      return -1;
    }
  }

226
  if (obu_payload_length > 0 &&
227 228
      obudec_read_obu_payload(f, obu_payload_length,
                              *obu_buffer + obu_bytes_buffered + bytes_read,
229 230 231
                              &bytes_read) != 0) {
    return -1;
  }
232

233 234 235 236 237 238 239 240 241
  *obu_length = bytes_read;
  return 0;
}

int file_is_obu(struct ObuDecInputContext *obu_ctx) {
  if (!obu_ctx || !obu_ctx->avx_ctx) return 0;

  struct AvxInputContext *avx_ctx = obu_ctx->avx_ctx;
  uint8_t detect_buf[OBU_DETECTION_SIZE] = { 0 };
242
  const int is_annexb = obu_ctx->is_annexb;
243
  FILE *f = avx_ctx->file;
244
  size_t payload_length = 0;
245 246
  ObuHeader obu_header;
  memset(&obu_header, 0, sizeof(obu_header));
247 248 249
  size_t length_of_unit_size = 0;
  size_t annexb_header_length = 0;
  uint64_t unit_size = 0;
250

251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
  if (is_annexb) {
    // read the size of first temporal unit
    if (obudec_read_leb128(f, &detect_buf[0], &length_of_unit_size,
                           &unit_size) != 0) {
      fprintf(stderr, "obudec: Failure reading temporal unit header\n");
      return 0;
    }

    // read the size of first frame unit
    if (obudec_read_leb128(f, &detect_buf[length_of_unit_size],
                           &annexb_header_length, &unit_size) != 0) {
      fprintf(stderr, "obudec: Failure reading frame unit header\n");
      return 0;
    }
    annexb_header_length += length_of_unit_size;
  }

268
  size_t bytes_read = 0;
269 270 271 272
  if (obudec_read_obu_header_and_size(
          f, OBU_DETECTION_SIZE - annexb_header_length, is_annexb,
          &detect_buf[annexb_header_length], &bytes_read, &payload_length,
          &obu_header) != 0) {
273 274
    fprintf(stderr, "obudec: Failure reading first OBU.\n");
    rewind(f);
275 276
    return 0;
  }
277

278 279 280 281
  if (is_annexb) {
    bytes_read += annexb_header_length;
  }

282 283 284 285
  if (obu_header.type != OBU_TEMPORAL_DELIMITER &&
      obu_header.type != OBU_SEQUENCE_HEADER) {
    return 0;
  }
286

287
  if (obu_header.has_size_field) {
288
    if (obu_header.type == OBU_TEMPORAL_DELIMITER && payload_length != 0) {
289 290 291 292 293 294
      fprintf(
          stderr,
          "obudec: Invalid OBU_TEMPORAL_DELIMITER payload length (non-zero).");
      rewind(f);
      return 0;
    }
295
  } else if (!is_annexb) {
296 297
    fprintf(stderr, "obudec: OBU size fields required, cannot decode input.\n");
    rewind(f);
298
    return 0;
299
  }
300 301

  // Appears that input is valid Section 5 AV1 stream.
302
  obu_ctx->buffer = (uint8_t *)malloc(OBU_BUFFER_SIZE);
303 304 305
  if (!obu_ctx->buffer) {
    fprintf(stderr, "Out of memory.\n");
    rewind(f);
306 307
    return 0;
  }
308
  obu_ctx->buffer_capacity = OBU_BUFFER_SIZE;
309

310 311
  memcpy(obu_ctx->buffer, &detect_buf[0], bytes_read);
  obu_ctx->bytes_buffered = bytes_read;
312 313 314 315 316 317 318 319
  // If the first OBU is a SEQUENCE_HEADER, then it will have a payload.
  // We need to read this in so that our buffer only contains complete OBUs.
  if (payload_length > 0) {
    if (payload_length > (obu_ctx->buffer_capacity - bytes_read)) {
      fprintf(stderr, "obudec: First OBU's payload is too large\n");
      rewind(f);
      return 0;
    }
320

321
    size_t payload_bytes = 0;
322 323 324 325 326 327 328 329
    const int status = obudec_read_obu_payload(
        f, payload_length, &obu_ctx->buffer[bytes_read], &payload_bytes);
    if (status < 0) {
      rewind(f);
      return 0;
    }
    obu_ctx->bytes_buffered += payload_bytes;
  }
330 331 332
  return 1;
}

333 334
int obudec_read_temporal_unit(struct ObuDecInputContext *obu_ctx,
                              uint8_t **buffer, size_t *bytes_read,
335
                              size_t *buffer_size) {
336
  FILE *f = obu_ctx->avx_ctx->file;
337
  if (!f) return -1;
338 339 340 341 342 343 344 345

  *buffer_size = 0;
  *bytes_read = 0;

  if (feof(f)) {
    return 1;
  }

346 347 348
  size_t tu_size;
  size_t obu_size = 0;
  size_t length_of_temporal_unit_size = 0;
349
  uint8_t tuheader[OBU_MAX_LENGTH_FIELD_SIZE] = { 0 };
350

351 352
  if (obu_ctx->is_annexb) {
    uint64_t size = 0;
353

354 355 356 357 358 359 360 361 362 363 364 365
    if (obu_ctx->bytes_buffered == 0) {
      if (obudec_read_leb128(f, &tuheader[0], &length_of_temporal_unit_size,
                             &size) != 0) {
        fprintf(stderr, "obudec: Failure reading temporal unit header\n");
        return -1;
      }
      if (size == 0 && feof(f)) {
        return 1;
      }
    } else {
      // temporal unit size was already stored in buffer
      if (aom_uleb_decode(obu_ctx->buffer, obu_ctx->bytes_buffered, &size,
366
                          &length_of_temporal_unit_size) != 0) {
367 368 369
        fprintf(stderr, "obudec: Failure reading temporal unit header\n");
        return -1;
      }
370 371 372 373 374
    }

    if (size > UINT32_MAX || size + length_of_temporal_unit_size > UINT32_MAX) {
      fprintf(stderr, "obudec: TU too large.\n");
      return -1;
375 376
    }

377
    size += length_of_temporal_unit_size;
378
    tu_size = (size_t)size;
379 380 381 382
  } else {
    while (1) {
      ObuHeader obu_header;
      memset(&obu_header, 0, sizeof(obu_header));
383

384 385 386
      if (obudec_read_one_obu(f, &obu_ctx->buffer, obu_ctx->bytes_buffered,
                              &obu_ctx->buffer_capacity, &obu_size, &obu_header,
                              0) != 0) {
387
        fprintf(stderr, "obudec: read_one_obu failed in TU loop\n");
388 389
        return -1;
      }
390

391
      if (obu_header.type == OBU_TEMPORAL_DELIMITER || obu_size == 0) {
392 393 394
        tu_size = obu_ctx->bytes_buffered;
        break;
      } else {
395
        obu_ctx->bytes_buffered += obu_size;
396 397 398 399 400 401 402 403 404
      }
    }
  }

#if defined AOM_MAX_ALLOCABLE_MEMORY
  if (tu_size > AOM_MAX_ALLOCABLE_MEMORY) {
    fprintf(stderr, "obudec: Temporal Unit size exceeds max alloc size.\n");
    return -1;
  }
405
#endif
406
  uint8_t *new_buffer = (uint8_t *)realloc(*buffer, tu_size);
407 408 409 410 411 412
  if (!new_buffer) {
    free(*buffer);
    fprintf(stderr, "obudec: Out of memory.\n");
    return -1;
  }
  *buffer = new_buffer;
413 414
  *bytes_read = tu_size;
  *buffer_size = tu_size;
415 416

  if (!obu_ctx->is_annexb) {
417
    memcpy(*buffer, obu_ctx->buffer, tu_size);
418

419 420 421
    // At this point, (obu_ctx->buffer + obu_ctx->bytes_buffered + obu_size)
    // points to the end of the buffer.
    memmove(obu_ctx->buffer, obu_ctx->buffer + obu_ctx->bytes_buffered,
422 423
            obu_size);
    obu_ctx->bytes_buffered = obu_size;
424 425 426 427 428
  } else {
    if (!feof(f)) {
      size_t data_size;
      size_t offset;
      if (!obu_ctx->bytes_buffered) {
429
        data_size = tu_size - length_of_temporal_unit_size;
430 431 432 433 434 435 436
        memcpy(*buffer, &tuheader[0], length_of_temporal_unit_size);
        offset = length_of_temporal_unit_size;
      } else {
        memcpy(*buffer, obu_ctx->buffer, obu_ctx->bytes_buffered);
        offset = obu_ctx->bytes_buffered;
        data_size = tu_size - obu_ctx->bytes_buffered;
        obu_ctx->bytes_buffered = 0;
437 438
      }

439
      if (fread(*buffer + offset, 1, data_size, f) != data_size) {
440 441 442
        fprintf(stderr, "obudec: Failed to read full temporal unit\n");
        return -1;
      }
443 444 445 446 447 448
    }
  }
  return 0;
}

void obudec_free(struct ObuDecInputContext *obu_ctx) { free(obu_ctx->buffer); }