Cyril Concolato | 6c78883 | 2017-10-30 16:30:35 -0700 | [diff] [blame] | 1 | /* |
| 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 <stdio.h> |
| 13 | #include <stdlib.h> |
| 14 | #include <string.h> |
| 15 | |
| 16 | #include "./obudec.h" |
| 17 | |
| 18 | #include "aom_ports/mem_ops.h" |
| 19 | #include "av1/common/common.h" |
| 20 | |
| 21 | #define OBU_HEADER_SIZE_BYTES 1 |
Soo-Chul Han | f858986 | 2018-01-24 03:13:14 +0000 | [diff] [blame] | 22 | #if CONFIG_SCALABILITY |
| 23 | #define OBU_HEADER_EXTENSION_SIZE_BYTES 1 |
| 24 | #endif |
Cyril Concolato | 6c78883 | 2017-10-30 16:30:35 -0700 | [diff] [blame] | 25 | |
| 26 | #if CONFIG_OBU_NO_IVF |
| 27 | int obu_read_temporal_unit(FILE *infile, uint8_t **buffer, size_t *bytes_read, |
Soo-Chul Han | f858986 | 2018-01-24 03:13:14 +0000 | [diff] [blame] | 28 | #if CONFIG_SCALABILITY |
| 29 | size_t *buffer_size, int last_layer_id) { |
| 30 | #else |
Cyril Concolato | 6c78883 | 2017-10-30 16:30:35 -0700 | [diff] [blame] | 31 | size_t *buffer_size) { |
Soo-Chul Han | f858986 | 2018-01-24 03:13:14 +0000 | [diff] [blame] | 32 | #endif |
Cyril Concolato | 6c78883 | 2017-10-30 16:30:35 -0700 | [diff] [blame] | 33 | size_t ret; |
| 34 | const size_t obu_length_header_size = |
| 35 | PRE_OBU_SIZE_BYTES + OBU_HEADER_SIZE_BYTES; |
Hui Su | e19c321 | 2018-02-21 14:32:18 -0800 | [diff] [blame] | 36 | uint64_t obu_size = 0; |
Cyril Concolato | 6c78883 | 2017-10-30 16:30:35 -0700 | [diff] [blame] | 37 | uint8_t *data = NULL; |
| 38 | |
| 39 | if (feof(infile)) { |
| 40 | return 1; |
| 41 | } |
| 42 | |
| 43 | *buffer_size = 0; |
| 44 | *bytes_read = 0; |
| 45 | while (1) { |
| 46 | // augment the buffer to just contain the next size field |
| 47 | // and the first byte of the header |
| 48 | *buffer = realloc(*buffer, (*buffer_size) + obu_length_header_size); |
| 49 | data = *buffer + (*buffer_size); |
| 50 | *buffer_size += obu_length_header_size; |
| 51 | ret = fread(data, 1, obu_length_header_size, infile); |
| 52 | if (ret == 0) { |
| 53 | // fprintf(stderr, "Found end of stream, ending temporal unit\n"); |
| 54 | break; |
| 55 | } |
| 56 | if (ret != obu_length_header_size) { |
| 57 | warn("Failed to read OBU Header\n"); |
| 58 | return 1; |
| 59 | } |
| 60 | *bytes_read += obu_length_header_size; |
| 61 | |
| 62 | if (((data[PRE_OBU_SIZE_BYTES] >> 3) & 0xF) == OBU_TEMPORAL_DELIMITER) { |
| 63 | // Stop when a temporal delimiter is found |
| 64 | // fprintf(stderr, "Found temporal delimiter, ending temporal unit\n"); |
| 65 | // prevent decoder to start decoding another frame from this buffer |
| 66 | *bytes_read -= obu_length_header_size; |
| 67 | break; |
| 68 | } |
| 69 | |
Soo-Chul Han | f858986 | 2018-01-24 03:13:14 +0000 | [diff] [blame] | 70 | #if CONFIG_SCALABILITY |
| 71 | // break if obu_extension_flag is found and enhancement_id change |
| 72 | if ((data[PRE_OBU_SIZE_BYTES] & 0x1)) { |
| 73 | uint8_t obu_extension_header; |
Hui Su | e19c321 | 2018-02-21 14:32:18 -0800 | [diff] [blame] | 74 | const int total_obu_header_size = |
Soo-Chul Han | f858986 | 2018-01-24 03:13:14 +0000 | [diff] [blame] | 75 | (int)obu_length_header_size + OBU_HEADER_EXTENSION_SIZE_BYTES; |
| 76 | int curr_layer_id; |
Hui Su | e19c321 | 2018-02-21 14:32:18 -0800 | [diff] [blame] | 77 | ret = fread(&obu_extension_header, 1, OBU_HEADER_EXTENSION_SIZE_BYTES, |
| 78 | infile); |
| 79 | if (ret != OBU_HEADER_EXTENSION_SIZE_BYTES) { |
| 80 | warn("Failed to read OBU Header Extension\n"); |
| 81 | return 1; |
| 82 | } |
Soo-Chul Han | f858986 | 2018-01-24 03:13:14 +0000 | [diff] [blame] | 83 | curr_layer_id = (obu_extension_header >> 3) & 0x3; |
| 84 | if (curr_layer_id && (curr_layer_id > last_layer_id)) { |
| 85 | // new enhancement layer |
| 86 | *bytes_read -= obu_length_header_size; |
| 87 | fseek(infile, -total_obu_header_size, SEEK_CUR); |
| 88 | break; |
| 89 | } else { |
| 90 | fseek(infile, -OBU_HEADER_EXTENSION_SIZE_BYTES, SEEK_CUR); |
| 91 | } |
| 92 | } |
| 93 | #endif |
| 94 | |
Tom Finegan | 41150ad | 2018-01-23 11:42:55 -0800 | [diff] [blame] | 95 | // otherwise, read the OBU payload into memory |
| 96 | #if CONFIG_OBU_SIZING |
David Barker | 0debbaa | 2018-02-23 14:39:01 +0000 | [diff] [blame] | 97 | aom_uleb_decode(data, PRE_OBU_SIZE_BYTES, &obu_size, NULL); |
Tom Finegan | 41150ad | 2018-01-23 11:42:55 -0800 | [diff] [blame] | 98 | #else |
Cyril Concolato | 6c78883 | 2017-10-30 16:30:35 -0700 | [diff] [blame] | 99 | obu_size = mem_get_le32(data); |
Tom Finegan | 41150ad | 2018-01-23 11:42:55 -0800 | [diff] [blame] | 100 | #endif // CONFIG_OBU_SIZING |
| 101 | |
Cyril Concolato | 6c78883 | 2017-10-30 16:30:35 -0700 | [diff] [blame] | 102 | // fprintf(stderr, "Found OBU of type %d and size %d\n", |
| 103 | // ((data[PRE_OBU_SIZE_BYTES] >> 3) & 0xF), obu_size); |
| 104 | obu_size--; // removing the byte of the header already read |
| 105 | if (obu_size) { |
| 106 | *buffer = realloc(*buffer, (*buffer_size) + obu_size); |
| 107 | data = *buffer + (*buffer_size); |
| 108 | *buffer_size += obu_size; |
| 109 | ret = fread(data, 1, obu_size, infile); |
| 110 | if (ret != obu_size) { |
| 111 | warn("Failed to read OBU Payload\n"); |
| 112 | return 1; |
| 113 | } |
| 114 | *bytes_read += obu_size; |
| 115 | } |
| 116 | } |
| 117 | return 0; |
| 118 | } |
| 119 | |
| 120 | int file_is_obu(struct AvxInputContext *input_ctx) { |
| 121 | uint8_t obutd[PRE_OBU_SIZE_BYTES + OBU_HEADER_SIZE_BYTES]; |
Hui Su | e19c321 | 2018-02-21 14:32:18 -0800 | [diff] [blame] | 122 | uint64_t size; |
Cyril Concolato | 6c78883 | 2017-10-30 16:30:35 -0700 | [diff] [blame] | 123 | |
Cyril Concolato | 6c78883 | 2017-10-30 16:30:35 -0700 | [diff] [blame] | 124 | // Reading the first OBU TD to enable TU end detection at TD start. |
Hui Su | e19c321 | 2018-02-21 14:32:18 -0800 | [diff] [blame] | 125 | const size_t obu_length_header_size = |
| 126 | PRE_OBU_SIZE_BYTES + OBU_HEADER_SIZE_BYTES; |
| 127 | const size_t ret = fread(obutd, 1, obu_length_header_size, input_ctx->file); |
| 128 | if (ret != obu_length_header_size) { |
| 129 | warn("Failed to read OBU Header\n"); |
| 130 | return 0; |
| 131 | } |
Tom Finegan | 41150ad | 2018-01-23 11:42:55 -0800 | [diff] [blame] | 132 | |
| 133 | #if CONFIG_OBU_SIZING |
David Barker | 0debbaa | 2018-02-23 14:39:01 +0000 | [diff] [blame] | 134 | aom_uleb_decode(obutd, PRE_OBU_SIZE_BYTES, &size, NULL); |
Tom Finegan | 41150ad | 2018-01-23 11:42:55 -0800 | [diff] [blame] | 135 | #else |
Cyril Concolato | 6c78883 | 2017-10-30 16:30:35 -0700 | [diff] [blame] | 136 | size = mem_get_le32(obutd); |
Tom Finegan | 41150ad | 2018-01-23 11:42:55 -0800 | [diff] [blame] | 137 | #endif // CONFIG_OBU_SIZING |
| 138 | |
Cyril Concolato | 6c78883 | 2017-10-30 16:30:35 -0700 | [diff] [blame] | 139 | if (size != 1) { |
| 140 | warn("Expected first OBU size to be 1, got %d", size); |
| 141 | return 0; |
| 142 | } |
| 143 | if (((obutd[PRE_OBU_SIZE_BYTES] >> 3) & 0xF) != OBU_TEMPORAL_DELIMITER) { |
| 144 | warn("Expected OBU TD at file start, got %d\n", obutd[PRE_OBU_SIZE_BYTES]); |
| 145 | return 0; |
| 146 | } |
| 147 | // fprintf(stderr, "Starting to parse OBU stream\n"); |
Soo-Chul Han | f858986 | 2018-01-24 03:13:14 +0000 | [diff] [blame] | 148 | |
Cyril Concolato | 6c78883 | 2017-10-30 16:30:35 -0700 | [diff] [blame] | 149 | return 1; |
| 150 | } |
| 151 | |
| 152 | #endif |