Commit 8acdbfc1 authored by Soo-Chul Han's avatar Soo-Chul Han Committed by Tom Finegan

replace Annex-B with Annex-B-prime

Annex-B-prime has been fully adopted.
Replace Annex-B with Annex-B-prime for encoding/decoding

BUG=aomedia:1700

Change-Id: Ib1478daf9d78fd9684911e343b407b91c969e691
parent b356cddd
......@@ -1270,6 +1270,55 @@ static aom_codec_err_t encoder_encode(aom_codec_alg_priv_t *ctx,
if (frame_size) {
if (ctx->pending_cx_data == 0) ctx->pending_cx_data = cx_data;
const int write_temporal_delimiter =
!cpi->common.enhancement_layer_id && !ctx->pending_frame_count;
if (write_temporal_delimiter) {
uint32_t obu_header_size = 1;
const uint32_t obu_payload_size = 0;
const size_t length_field_size =
aom_uleb_size_in_bytes(obu_payload_size);
if (ctx->pending_cx_data) {
const size_t move_offset = length_field_size + 1;
memmove(ctx->pending_cx_data + move_offset, ctx->pending_cx_data,
frame_size);
}
const uint32_t obu_header_offset = 0;
obu_header_size = write_obu_header(
OBU_TEMPORAL_DELIMITER, 0,
(uint8_t *)(ctx->pending_cx_data + obu_header_offset));
// OBUs are preceded/succeeded by an unsigned leb128 coded integer.
if (write_uleb_obu_size(obu_header_size, obu_payload_size,
ctx->pending_cx_data) != AOM_CODEC_OK) {
return AOM_CODEC_ERROR;
}
frame_size += obu_header_size + obu_payload_size + length_field_size;
}
if (ctx->oxcf.save_as_annexb) {
size_t curr_frame_size = frame_size;
if (av1_convert_sect5obus_to_annexb(cx_data, &curr_frame_size) !=
AOM_CODEC_OK) {
return AOM_CODEC_ERROR;
}
frame_size = curr_frame_size;
// B_PRIME (add frame size)
const size_t length_field_size = aom_uleb_size_in_bytes(frame_size);
if (ctx->pending_cx_data) {
const size_t move_offset = length_field_size;
memmove(cx_data + move_offset, cx_data, frame_size);
}
if (write_uleb_obu_size(0, (uint32_t)frame_size, cx_data) !=
AOM_CODEC_OK) {
return AOM_CODEC_ERROR;
}
frame_size += length_field_size;
}
ctx->pending_frame_sizes[ctx->pending_frame_count++] = frame_size;
ctx->pending_cx_data_sz += frame_size;
......@@ -1285,50 +1334,27 @@ static aom_codec_err_t encoder_encode(aom_codec_alg_priv_t *ctx,
// Add the frame packet to the list of returned packets.
aom_codec_cx_pkt_t pkt;
pkt.kind = AOM_CODEC_CX_FRAME_PKT;
pkt.data.frame.buf = ctx->pending_cx_data;
pkt.data.frame.sz = ctx->pending_cx_data_sz;
pkt.data.frame.partition_id = -1;
int write_temporal_delimiter = 1;
// only write OBU_TD if base layer
write_temporal_delimiter = !cpi->common.enhancement_layer_id;
if (write_temporal_delimiter) {
// move data and insert OBU_TD preceded by optional 4 byte size
uint32_t obu_header_size = 1;
const uint32_t obu_payload_size = 0;
const size_t length_field_size =
aom_uleb_size_in_bytes(obu_payload_size);
if (ctx->oxcf.save_as_annexb) {
// B_PRIME (add TU size)
size_t tu_size = ctx->pending_cx_data_sz;
const size_t length_field_size = aom_uleb_size_in_bytes(tu_size);
if (ctx->pending_cx_data) {
const size_t move_offset = length_field_size + 1;
const size_t move_offset = length_field_size;
memmove(ctx->pending_cx_data + move_offset, ctx->pending_cx_data,
ctx->pending_cx_data_sz);
tu_size);
}
const uint32_t obu_header_offset = 0;
obu_header_size = write_obu_header(
OBU_TEMPORAL_DELIMITER, 0,
(uint8_t *)(ctx->pending_cx_data + obu_header_offset));
// OBUs are preceded/succeeded by an unsigned leb128 coded integer.
if (write_uleb_obu_size(obu_header_size, obu_payload_size,
ctx->pending_cx_data) != AOM_CODEC_OK) {
if (write_uleb_obu_size(0, (uint32_t)tu_size, ctx->pending_cx_data) !=
AOM_CODEC_OK) {
return AOM_CODEC_ERROR;
}
pkt.data.frame.sz +=
obu_header_size + obu_payload_size + length_field_size;
ctx->pending_cx_data_sz += length_field_size;
}
if (ctx->oxcf.save_as_annexb) {
size_t curr_frame_size = pkt.data.frame.sz;
if (av1_convert_sect5obus_to_annexb(ctx->pending_cx_data,
&curr_frame_size) != AOM_CODEC_OK) {
return AOM_CODEC_ERROR;
}
pkt.data.frame.sz = curr_frame_size;
}
pkt.kind = AOM_CODEC_CX_FRAME_PKT;
pkt.data.frame.buf = ctx->pending_cx_data;
pkt.data.frame.sz = ctx->pending_cx_data_sz;
pkt.data.frame.partition_id = -1;
pkt.data.frame.pts = ticks_to_timebase_units(timebase, dst_time_stamp);
pkt.data.frame.flags = get_frame_pkt_flags(cpi, lib_flags);
......
......@@ -477,6 +477,17 @@ static aom_codec_err_t decoder_decode(aom_codec_alg_priv_t *ctx,
if (res != AOM_CODEC_OK) return res;
}
if (ctx->is_annexb) {
// read the size of this temporal unit
size_t length_of_size;
uint64_t size_of_unit;
if (aom_uleb_decode(data_start, data_sz, &size_of_unit, &length_of_size) !=
0) {
return AOM_CODEC_CORRUPT_FRAME;
}
data_start += length_of_size;
}
// Decode in serial mode.
if (frame_count > 0) {
int i;
......@@ -496,6 +507,17 @@ static aom_codec_err_t decoder_decode(aom_codec_alg_priv_t *ctx,
}
} else {
while (data_start < data_end) {
if (ctx->is_annexb) {
// read the size of this frame unit
size_t length_of_size;
uint64_t size_of_frame_unit;
if (aom_uleb_decode(data_start, (uint32_t)(data_end - data_start),
&size_of_frame_unit, &length_of_size) != 0) {
return AOM_CODEC_CORRUPT_FRAME;
}
data_start += length_of_size;
}
const uint32_t frame_size = (uint32_t)(data_end - data_start);
res = decode_one(ctx, &data_start, frame_size, user_priv);
if (res != AOM_CODEC_OK) return res;
......
......@@ -25,7 +25,7 @@
#define OBU_EXTENSION_SIZE 1
#define OBU_MAX_LENGTH_FIELD_SIZE 8
#define OBU_DETECTION_SIZE \
(OBU_HEADER_SIZE + OBU_EXTENSION_SIZE + OBU_MAX_LENGTH_FIELD_SIZE)
(OBU_HEADER_SIZE + OBU_EXTENSION_SIZE + 2 * OBU_MAX_LENGTH_FIELD_SIZE)
// 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',
......@@ -209,9 +209,30 @@ int file_is_obu(struct ObuDecInputContext *obu_ctx) {
uint64_t obu_length = 0;
ObuHeader obu_header;
memset(&obu_header, 0, sizeof(obu_header));
size_t length_of_unit_size = 0;
uint64_t unit_size;
size_t annexb_header_length = 0;
if (obudec_read_one_obu(f, OBU_DETECTION_SIZE, is_annexb, &detect_buf[0],
&obu_length, &obu_header) != 0) {
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;
}
if (obudec_read_one_obu(f, OBU_DETECTION_SIZE, is_annexb,
&detect_buf[annexb_header_length], &obu_length,
&obu_header) != 0) {
fprintf(stderr, "obudec: Failure reading first OBU.\n");
rewind(f);
return 0;
......@@ -250,6 +271,10 @@ int file_is_obu(struct ObuDecInputContext *obu_ctx) {
return 0;
}
obu_ctx->buffer_capacity = OBU_BUFFER_SIZE;
if (is_annexb) {
obu_length += annexb_header_length;
}
memcpy(obu_ctx->buffer, &detect_buf[0], (size_t)obu_length);
obu_ctx->bytes_buffered = (size_t)obu_length;
......@@ -269,51 +294,102 @@ int obudec_read_temporal_unit(struct ObuDecInputContext *obu_ctx,
return 1;
}
const int is_annexb = obu_ctx->is_annexb;
while (1) {
ObuHeader obu_header;
memset(&obu_header, 0, sizeof(obu_header));
size_t tu_size;
uint64_t obu_size = 0;
uint8_t *data = obu_ctx->buffer;
size_t length_of_temporal_unit_size = 0;
uint8_t tuheader[OBU_MAX_LENGTH_FIELD_SIZE] = { 0 };
uint64_t obu_size = 0;
uint8_t *data = obu_ctx->buffer + obu_ctx->bytes_buffered;
const size_t capacity = obu_ctx->buffer_capacity - obu_ctx->bytes_buffered;
if (obu_ctx->is_annexb) {
uint64_t size = 0;
if (obudec_read_one_obu(f, capacity, is_annexb, data, &obu_size,
&obu_header) != 0) {
fprintf(stderr, "obudec: read_one_obu failed in TU loop\n");
return -1;
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,
&length_of_temporal_unit_size) != 0) {
fprintf(stderr, "obudec: Failure reading temporal unit header\n");
return -1;
}
}
if (obu_header.type == OBU_TEMPORAL_DELIMITER || obu_size == 0 ||
(obu_header.has_extension &&
obu_header.enhancement_layer_id > obu_ctx->last_layer_id)) {
const size_t tu_size = obu_ctx->bytes_buffered;
size += length_of_temporal_unit_size;
tu_size = (size_t)size;
} else {
while (1) {
ObuHeader obu_header;
memset(&obu_header, 0, sizeof(obu_header));
#if defined AOM_MAX_ALLOCABLE_MEMORY
if (tu_size > AOM_MAX_ALLOCABLE_MEMORY) {
fprintf(stderr, "obudec: Temporal Unit size exceeds max alloc size.\n");
data = obu_ctx->buffer + obu_ctx->bytes_buffered;
const size_t capacity =
obu_ctx->buffer_capacity - obu_ctx->bytes_buffered;
if (obudec_read_one_obu(f, capacity, 0, data, &obu_size, &obu_header) !=
0) {
fprintf(stderr, "obudec: read_one_obu failed in TU loop\n");
return -1;
}
if (obu_header.type == OBU_TEMPORAL_DELIMITER || obu_size == 0 ||
(obu_header.has_extension &&
obu_header.enhancement_layer_id > obu_ctx->last_layer_id)) {
tu_size = obu_ctx->bytes_buffered;
break;
} else {
obu_ctx->bytes_buffered += (size_t)obu_size;
}
}
}
#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;
}
#endif
uint8_t *new_buffer = (uint8_t *)realloc(*buffer, tu_size);
if (!new_buffer) {
free(*buffer);
fprintf(stderr, "obudec: Out of memory.\n");
return -1;
uint8_t *new_buffer = (uint8_t *)realloc(*buffer, tu_size);
if (!new_buffer) {
free(*buffer);
fprintf(stderr, "obudec: Out of memory.\n");
return -1;
}
*buffer = new_buffer;
*bytes_read = tu_size;
*buffer_size = tu_size;
if (!obu_ctx->is_annexb) {
memcpy(*buffer, obu_ctx->buffer, tu_size);
memmove(obu_ctx->buffer, data, (size_t)obu_size);
obu_ctx->bytes_buffered = (size_t)obu_size;
} else {
if (!feof(f)) {
size_t data_size;
size_t offset;
if (!obu_ctx->bytes_buffered) {
data_size = (uint32_t)(tu_size - length_of_temporal_unit_size);
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;
}
*buffer = new_buffer;
*bytes_read = tu_size;
*buffer_size = tu_size;
memcpy(*buffer, obu_ctx->buffer, tu_size);
memmove(obu_ctx->buffer, data, (size_t)obu_size);
obu_ctx->bytes_buffered = (size_t)obu_size;
break;
} else {
obu_ctx->bytes_buffered += (size_t)obu_size;
if (fread(new_buffer + offset, 1, data_size, f) != data_size) {
fprintf(stderr, "obudec: Failed to read full temporal unit\n");
return -1;
}
}
}
return 0;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment