Skip to content

Commit

Permalink
backend: Allow users to set separate crops for each output
Browse files Browse the repository at this point in the history
For backward compatibility, we keep the existing BackEnd::SetCrop
behaving the same and setting the same crop params for all outputs.

Signed-off-by: Naushir Patuck <[email protected]>
  • Loading branch information
naushir committed May 1, 2024
1 parent 999da5a commit f615a08
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 32 deletions.
11 changes: 10 additions & 1 deletion src/libpisp/backend/backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,16 @@ void BackEnd::GetGamma(pisp_be_gamma_config &gamma)

void BackEnd::SetCrop(pisp_be_crop_config const &crop)
{
be_config_.crop = crop;
for (unsigned int i = 0; i < variant_.BackEndNumBranches(0); i++)
be_config_.crop[i] = crop;
be_config_.dirty_flags_extra |= PISP_BE_DIRTY_CROP;
retile_ = true;
}

void BackEnd::SetCrop(unsigned int i, pisp_be_crop_config const &crop)
{
PISP_ASSERT(i < variant_.BackEndNumBranches(0));
be_config_.crop[i] = crop;
be_config_.dirty_flags_extra |= PISP_BE_DIRTY_CROP;
retile_ = true;
}
Expand Down
1 change: 1 addition & 0 deletions src/libpisp/backend/backend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ class BackEnd
void SetGamma(pisp_be_gamma_config const &gamma);
void GetGamma(pisp_be_gamma_config &gamma);
void SetCrop(pisp_be_crop_config const &crop);
void SetCrop(unsigned int i, pisp_be_crop_config const &crop);
void SetCsc(unsigned int i, pisp_be_ccm_config const &csc);
void GetCsc(unsigned int i, pisp_be_ccm_config &csc);
void SetOutputFormat(unsigned int i, pisp_be_output_format_config const &output_format);
Expand Down
45 changes: 23 additions & 22 deletions src/libpisp/backend/backend_prepare.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,8 +488,8 @@ void BackEnd::finaliseConfig()
if (enabled)
{
// crop is enabled when it contains non-zero width/height
uint16_t w = be_config_.crop.width ? be_config_.crop.width : be_config_.input_format.width;
uint16_t h = be_config_.crop.width ? be_config_.crop.height : be_config_.input_format.height;
uint16_t w = be_config_.crop[j].width ? be_config_.crop[j].width : be_config_.input_format.width;
uint16_t h = be_config_.crop[j].width ? be_config_.crop[j].height : be_config_.input_format.height;

if (dirty_flags_rgb & PISP_BE_RGB_ENABLE_DOWNSCALE(j))
{
Expand Down Expand Up @@ -535,18 +535,18 @@ void BackEnd::updateSmartResize()
{
std::string filter;

// First get the size of the input to the rescalers. The crops are zero when not in use.
uint16_t input_width = be_config_.crop.width;
if (!input_width)
input_width = be_config_.input_format.width;
uint16_t input_height = be_config_.crop.height;
if (!input_height)
input_height = be_config_.input_format.height;

// Look through the output branches adjusting the scaling blocks where "smart resizing"
// has been requested.
for (unsigned int i = 0; i < variant_.BackEndNumBranches(0); i++)
{
// First get the size of the input to the rescalers. The crops are zero when not in use.
uint16_t input_width = be_config_.crop[i].width;
if (!input_width)
input_width = be_config_.input_format.width;
uint16_t input_height = be_config_.crop[i].height;
if (!input_height)
input_height = be_config_.input_format.height;

if ((smart_resize_dirty_ & (1 << i)) || (be_config_.dirty_flags_extra & PISP_BE_DIRTY_CROP))
{
if (smart_resize_[i].width && smart_resize_[i].height)
Expand Down Expand Up @@ -688,15 +688,16 @@ void BackEnd::updateTiles()
PISP_LOG(debug, "Input alignments are " << tiling_config.input_alignment << " pixels");

tiling_config.input_image_size = tiling::Length2(c.input_format.width, c.input_format.height);
tiling_config.crop = tiling::Interval2(tiling::Interval(c.crop.offset_x, c.crop.width),
tiling::Interval(c.crop.offset_y, c.crop.height));

if (tiling_config.crop.x.length == 0 || tiling_config.crop.y.length == 0)
tiling_config.crop = tiling::Interval2(tiling::Interval(0, c.input_format.width),
tiling::Interval(0, c.input_format.height));

for (unsigned int i = 0; i < variant_.BackEndNumBranches(0); i++)
{
tiling_config.crop[i] = tiling::Interval2(tiling::Interval(c.crop[i].offset_x, c.crop[i].width),
tiling::Interval(c.crop[i].offset_y, c.crop[i].height));

if (tiling_config.crop[i].x.length == 0 || tiling_config.crop[i].y.length == 0)
tiling_config.crop[i] = tiling::Interval2(tiling::Interval(0, c.input_format.width),
tiling::Interval(0, c.input_format.height));

tiling_config.output_h_mirror[i] = be_config_.output_format[i].transform & PISP_BE_TRANSFORM_HFLIP;
tiling_config.downscale_factor[i] =
tiling::Length2(c.downscale[i].scale_factor_h, c.downscale[i].scale_factor_v);
Expand Down Expand Up @@ -791,25 +792,25 @@ std::vector<pisp_tile> BackEnd::retilePipeline(TilingConfig const &tiling_config
}

tiling::Crop2 downscale_crop;
tiling::Interval2 resample_size = tiles[i].crop.output;
tiling::Interval2 resample_size = tiles[i].crop[j].output;
resample_size.x = resample_size.x - tiles[i].resample[j].crop.x;
resample_size.y = resample_size.y - tiles[i].resample[j].crop.y;

// When a resize stage is disabled, the tile size after the stage is found from the input of the
// next block. Also there will be no extra crop necessary for the resize operation.
if (be_config_.global.rgb_enables & PISP_BE_RGB_ENABLE_DOWNSCALE(j))
{
downscale_crop = tiles[i].downscale[j].crop + tiles[i].crop.crop;
downscale_crop = tiles[i].downscale[j].crop + tiles[i].crop[j].crop;
// Size of the tile going into the resample block needs to be set here.
resample_size = tiles[i].downscale[j].output;
}
else if (be_config_.global.rgb_enables & PISP_BE_RGB_ENABLE_RESAMPLE(j))
{
downscale_crop = tiles[i].resample[j].crop + tiles[i].crop.crop;
downscale_crop = tiles[i].resample[j].crop + tiles[i].crop[j].crop;
}
else
{
downscale_crop = tiles[i].output[j].crop + tiles[i].crop.crop;
downscale_crop = tiles[i].output[j].crop + tiles[i].crop[j].crop;
}

t.crop_x_start[j] = downscale_crop.x.start;
Expand Down Expand Up @@ -949,8 +950,8 @@ void BackEnd::getOutputSize(int i, uint16_t *width, uint16_t *height, pisp_image
*width = be_config_.resample_extra[i].scaled_width, *height = be_config_.resample_extra[i].scaled_height;
else if (be_config_.global.rgb_enables & PISP_BE_RGB_ENABLE_DOWNSCALE(i))
*width = be_config_.downscale_extra[i].scaled_width, *height = be_config_.downscale_extra[i].scaled_height;
else if (be_config_.crop.width) // crop width and height will be zero when crop disabled
*width = be_config_.crop.width, *height = be_config_.crop.height;
else if (be_config_.crop[i].width) // crop width and height will be zero when crop disabled
*width = be_config_.crop[i].width, *height = be_config_.crop[i].height;
else
*width = ifmt.width, *height = ifmt.height;
}
Expand Down
4 changes: 2 additions & 2 deletions src/libpisp/backend/pisp_be_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ typedef struct {
pisp_be_downscale_extra
downscale_extra[PISP_BACK_END_NUM_OUTPUTS];
pisp_be_resample_extra resample_extra[PISP_BACK_END_NUM_OUTPUTS];
pisp_be_crop_config crop;
pisp_be_crop_config crop[PISP_BACK_END_NUM_OUTPUTS];
pisp_image_format_config hog_format;
uint32_t dirty_flags_bayer; /* these use pisp_be_bayer_enable */
uint32_t dirty_flags_rgb; /* use pisp_be_rgb_enable */
Expand Down Expand Up @@ -523,9 +523,9 @@ typedef struct {
static_assert(sizeof(pisp_tile) == 160, "pisp_tile not packed as expected");

typedef struct {
pisp_be_config config;
pisp_tile tiles[PISP_BACK_END_NUM_TILES];
int num_tiles;
pisp_be_config config;
} pisp_be_tiles_config;

#endif /* _PISP_BE_CONFIG_H_ */
11 changes: 7 additions & 4 deletions src/libpisp/backend/tiling/pisp_tiling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,9 @@ void tile_pipeline(TilingConfig const &config, Tile *tiles, int num_tiles, Lengt
Length2(PipelineAlignX, PipelineAlignY));
ContextStage context_stage("context", &input_stage, context_config, offsetof(Tile, context));

CropStage::Config crop_config(config.crop);
CropStage crop_stage("crop", &context_stage, crop_config, offsetof(Tile, crop));

SplitStage split_stage("split", &crop_stage);
SplitStage split_stage("split", &context_stage);

std::unique_ptr<Stage> crop_stages[NumOutputBranches];
std::unique_ptr<Stage> downscale_stages[NumOutputBranches];
std::unique_ptr<Stage> resample_stages[NumOutputBranches];
std::unique_ptr<Stage> output_stages[NumOutputBranches];
Expand All @@ -74,6 +72,11 @@ void tile_pipeline(TilingConfig const &config, Tile *tiles, int num_tiles, Lengt
char name[32];
Stage *prev_stage = &split_stage;

sprintf(name, "crop%d", i);
crop_stages[i] = std::unique_ptr<Stage>(
new CropStage(name, prev_stage, config.crop[i], offsetof(Tile, crop) + i * sizeof(Region)));
prev_stage = crop_stages[i].get();

// There's a little awkwardness if the resize blocks (downscale and resample) are not enabled. Resize *does* change the output tile
// size, even if it's doing a 1-to-1 scaling (it loses context), so we must leave it out of the tiling
// calculation.
Expand Down
6 changes: 3 additions & 3 deletions src/libpisp/backend/tiling/pisp_tiling.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct Tile
tiling::Region input;
tiling::Region decompress;
tiling::Region context;
tiling::Region crop;
tiling::Region crop[NumOutputBranches];
tiling::Region downscale[NumOutputBranches];
tiling::Region resample[NumOutputBranches];
tiling::Region output[NumOutputBranches];
Expand All @@ -31,7 +31,7 @@ struct Tile
struct TilingConfig
{
tiling::Length2 input_image_size;
tiling::Interval2 crop;
tiling::Interval2 crop[NumOutputBranches];
tiling::Length2 downscale_image_size[NumOutputBranches];
tiling::Length2 output_image_size[NumOutputBranches];
tiling::Length2 max_tile_size;
Expand All @@ -51,9 +51,9 @@ inline std::ostream &operator<<(std::ostream &os, TilingConfig const &tc)
{
os << "TilingConfig:" << std::endl;
os << "\tinput_image_size " << tc.input_image_size << " align " << tc.input_alignment << std::endl;
os << "\tcrop " << tc.crop << std::endl;
for (int i = 0; i < NumOutputBranches; i++)
{
os << "\tcrop[" << i << "] " << tc.crop[i] << std::endl;
os << "\toutput_image_size[" << i << "] " << tc.output_image_size[i] << " align max "
<< tc.output_max_alignment[i] << " min " << tc.output_min_alignment[i] << std::endl;
os << "\tdownscale_image_size " << tc.downscale_image_size[i] << " downscale_factor " << tc.downscale_factor[i]
Expand Down

0 comments on commit f615a08

Please sign in to comment.