blob: 3d67816bfffab067487f2eef9dd4a79a9e8c9d1c [file] [log] [blame] [edit]
/*
* Copyright (c) 2025, Alliance for Open Media. All rights reserved
*
* This source code is subject to the terms of the BSD 3-Clause Clear License
* and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
* License was not distributed with this source code in the LICENSE file, you
* can obtain it at aomedia.org/license/software-license/bsd-3-c-c/. 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
* aomedia.org/license/patent-license/.
*/
#include <assert.h>
#include <limits.h>
#include <stdio.h>
#include "aom/aom_encoder.h"
#include "aom_dsp/aom_dsp_common.h"
#include "aom_dsp/binary_codes_writer.h"
#include "aom_dsp/bitwriter_buffer.h"
#include "aom_mem/aom_mem.h"
#include "aom_ports/bitops.h"
#include "aom_ports/mem_ops.h"
#include "aom_ports/system_state.h"
#include "av1/common/av1_common_int.h"
#include "av1/common/blockd.h"
#include "av1/common/enums.h"
#if CONFIG_BITSTREAM_DEBUG
#include "aom_util/debug_util.h"
#endif // CONFIG_BITSTREAM_DEBUG
#include "common/md5_utils.h"
#include "common/rawenc.h"
#include "av1/encoder/bitstream.h"
#include "av1/encoder/tokenize.h"
static uint32_t write_ats_region_info(struct AtlasRegionInfo *atlas_reg_params,
int xlayerId, int xAId,
struct aom_write_bit_buffer *wb) {
aom_wb_write_uvlc(
wb, atlas_reg_params->ats_num_region_columns_minus_1[xlayerId][xAId]);
aom_wb_write_uvlc(
wb, atlas_reg_params->ats_num_region_rows_minus_1[xlayerId][xAId]);
aom_wb_write_bit(wb,
atlas_reg_params->ats_uniform_spacing_flag[xlayerId][xAId]);
if (!atlas_reg_params->ats_uniform_spacing_flag[xlayerId][xAId]) {
for (int i = 0;
i <
atlas_reg_params->ats_num_region_columns_minus_1[xlayerId][xAId] + 1;
i++) {
aom_wb_write_uvlc(
wb, atlas_reg_params->ats_column_width_minus_1[xlayerId][xAId][i]);
}
for (int i = 0;
i < atlas_reg_params->ats_num_region_rows_minus_1[xlayerId][xAId] + 1;
i++) {
aom_wb_write_uvlc(
wb, atlas_reg_params->ats_row_height_minus_1[xlayerId][xAId][i]);
}
} else {
aom_wb_write_uvlc(
wb, atlas_reg_params->ats_region_width_minus_1[xlayerId][xAId]);
aom_wb_write_uvlc(
wb, atlas_reg_params->ats_region_height_minus_1[xlayerId][xAId]);
}
return 0;
}
static uint32_t write_ats_multistream_atlas_info(
struct AtlasBasicInfo *ats_basic_info, int obu_xLayer_id, int xAId,
struct aom_write_bit_buffer *wb) {
aom_wb_write_uvlc(wb, ats_basic_info->ats_atlas_width[obu_xLayer_id][xAId]);
aom_wb_write_uvlc(wb, ats_basic_info->ats_atlas_height[obu_xLayer_id][xAId]);
aom_wb_write_uvlc(
wb, ats_basic_info->ats_num_atlas_segments_minus_1[obu_xLayer_id][xAId]);
const int NumSegments =
ats_basic_info->ats_num_atlas_segments_minus_1[obu_xLayer_id][xAId] + 1;
for (int i = 0; i < NumSegments; i++) {
aom_wb_write_literal(
wb, ats_basic_info->ats_input_stream_id[obu_xLayer_id][xAId][i], 5);
aom_wb_write_uvlc(
wb, ats_basic_info->ats_segment_top_left_pos_x[obu_xLayer_id][xAId][i]);
aom_wb_write_uvlc(
wb, ats_basic_info->ats_segment_top_left_pos_y[obu_xLayer_id][xAId][i]);
aom_wb_write_uvlc(
wb, ats_basic_info->ats_segment_width[obu_xLayer_id][xAId][i]);
aom_wb_write_uvlc(
wb, ats_basic_info->ats_segment_height[obu_xLayer_id][xAId][i]);
}
return 0;
}
static uint32_t write_ats_basic_info(struct AtlasBasicInfo *ats_basic_info,
int obu_xLayer_id, int xAId,
struct aom_write_bit_buffer *wb) {
aom_wb_write_bit(wb,
ats_basic_info->ats_stream_id_present[obu_xLayer_id][xAId]);
aom_wb_write_uvlc(wb, ats_basic_info->ats_atlas_width[obu_xLayer_id][xAId]);
aom_wb_write_uvlc(wb, ats_basic_info->ats_atlas_height[obu_xLayer_id][xAId]);
aom_wb_write_uvlc(
wb, ats_basic_info->ats_num_atlas_segments_minus_1[obu_xLayer_id][xAId]);
const int NumSegments =
ats_basic_info->ats_num_atlas_segments_minus_1[obu_xLayer_id][xAId] + 1;
for (int i = 0; i < NumSegments; i++) {
if (ats_basic_info->ats_stream_id_present[obu_xLayer_id][xAId]) {
aom_wb_write_literal(
wb, ats_basic_info->ats_input_stream_id[obu_xLayer_id][xAId][i], 5);
}
aom_wb_write_uvlc(
wb, ats_basic_info->ats_segment_top_left_pos_x[obu_xLayer_id][xAId][i]);
aom_wb_write_uvlc(
wb, ats_basic_info->ats_segment_top_left_pos_y[obu_xLayer_id][xAId][i]);
aom_wb_write_uvlc(
wb, ats_basic_info->ats_segment_width[obu_xLayer_id][xAId][i]);
aom_wb_write_uvlc(
wb, ats_basic_info->ats_segment_height[obu_xLayer_id][xAId][i]);
}
return 0;
}
static uint32_t write_ats_region_to_segment_mapping(
struct AtlasRegionToSegmentMapping *ats_reg_seg_map, int obu_xLayer_id,
int xAId, int NumRegionsInAtlas, struct aom_write_bit_buffer *wb) {
aom_wb_write_bit(
wb, ats_reg_seg_map
->ats_single_region_per_atlas_segment_flag[obu_xLayer_id][xAId]);
if (!ats_reg_seg_map
->ats_single_region_per_atlas_segment_flag[obu_xLayer_id][xAId]) {
aom_wb_write_uvlc(
wb,
ats_reg_seg_map->ats_num_atlas_segments_minus_1[obu_xLayer_id][xAId]);
const int NumSegments =
ats_reg_seg_map->ats_num_atlas_segments_minus_1[obu_xLayer_id][xAId] +
1;
for (int i = 0; i < NumSegments; i++) {
aom_wb_write_uvlc(
wb,
ats_reg_seg_map->ats_top_left_region_column[obu_xLayer_id][xAId][i]);
aom_wb_write_uvlc(
wb, ats_reg_seg_map->ats_top_left_region_row[obu_xLayer_id][xAId][i]);
aom_wb_write_uvlc(
wb, ats_reg_seg_map
->ats_bottom_right_region_column_off[obu_xLayer_id][xAId][i]);
aom_wb_write_uvlc(
wb, ats_reg_seg_map
->ats_bottom_right_region_row_off[obu_xLayer_id][xAId][i]);
}
} else
ats_reg_seg_map->ats_num_atlas_segments_minus_1[obu_xLayer_id][xAId] =
NumRegionsInAtlas - 1;
return 0;
}
static uint32_t write_ats_label_segment_info(AV1_COMP *cpi, int xLayerId,
int xAId,
struct aom_write_bit_buffer *wb) {
struct AtlasLabelSegmentInfo *ats_label =
&cpi->common.atlas_params.ats_label_seg;
struct AtlasRegionToSegmentMapping *ats_reg =
&cpi->common.atlas_params.ats_reg_seg_map;
aom_wb_write_bit(
wb, ats_label->ats_signalled_atlas_segment_ids_flag[xLayerId][xAId]);
if (ats_label->ats_signalled_atlas_segment_ids_flag[xLayerId][xAId]) {
const int NumSegments =
ats_reg->ats_num_atlas_segments_minus_1[xLayerId][xAId] + 1;
for (int i = 0; i < NumSegments; i++) {
aom_wb_write_literal(wb, ats_label->ats_atlas_segment_id[i],
ATLAS_LABEL_SEG_ID_BITS);
}
}
return 0;
}
uint32_t av1_write_atlas_segment_info_obu(AV1_COMP *cpi, int obu_xLayer_id,
uint8_t *const dst) {
struct aom_write_bit_buffer wb = { dst, 0 };
uint32_t size = 0;
struct AtlasSegmentInfo *atlas_params = &cpi->common.atlas_params;
aom_wb_write_literal(&wb, atlas_params->atlas_segment_id[obu_xLayer_id], 3);
int xAId = atlas_params->atlas_segment_id[obu_xLayer_id];
aom_wb_write_uvlc(&wb,
atlas_params->atlas_segment_mode_idc[obu_xLayer_id][xAId]);
if (atlas_params->atlas_segment_mode_idc[obu_xLayer_id][xAId] == ENH_ATLAS) {
write_ats_region_info(&atlas_params->ats_reg_params, obu_xLayer_id, xAId,
&wb);
write_ats_region_to_segment_mapping(
&atlas_params->ats_reg_seg_map, obu_xLayer_id, xAId,
atlas_params->ats_reg_params.NumRegionsInAtlas[obu_xLayer_id][xAId],
&wb);
} else if (atlas_params->atlas_segment_mode_idc[obu_xLayer_id][xAId] ==
BASIC_ATLAS) {
write_ats_basic_info(atlas_params->ats_basic_info, obu_xLayer_id, xAId,
&wb);
} else if (atlas_params->atlas_segment_mode_idc[obu_xLayer_id][xAId] ==
SINGLE_ATLAS) {
atlas_params->ats_reg_seg_map
.ats_num_atlas_segments_minus_1[obu_xLayer_id][xAId] = 0;
aom_wb_write_uvlc(
&wb, atlas_params->ats_nominal_width_minus1[obu_xLayer_id][xAId]);
aom_wb_write_uvlc(
&wb, atlas_params->ats_nominal_height_minus1[obu_xLayer_id][xAId]);
} else if (atlas_params->atlas_segment_mode_idc[obu_xLayer_id][xAId] ==
MULTISTREAM_ATLAS) {
write_ats_multistream_atlas_info(atlas_params->ats_basic_info,
obu_xLayer_id, xAId, &wb);
}
// Label each atlas segment
write_ats_label_segment_info(cpi, obu_xLayer_id, xAId, &wb);
av1_add_trailing_bits(&wb);
size = aom_wb_bytes_written(&wb);
return size;
}
int av1_set_atlas_segment_info_params(AV1_COMP *cpi,
struct AtlasSegmentInfo *atlas,
int layer_id) {
(void)layer_id;
AV1_COMMON *cm = &cpi->common;
memcpy(atlas, cm->atlas, sizeof(struct AtlasSegmentInfo));
atlas->atlas_segment_id[0] = 1;
return 0;
}