blob: e7306f62551c0d34c1b0a781988e63b376ff424b [file] [log] [blame]
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// -----------------------------------------------------------------------------
//
// Tile-related structs.
//
// Author: Skal (pascal.massimino@gmail.com)
#ifndef WP2_DEC_TILE_DEC_H_
#define WP2_DEC_TILE_DEC_H_
#include "src/common/progress_watcher.h"
#include "src/dec/filters/block_map_filter.h"
#include "src/utils/csp.h"
#include "src/utils/data_source.h"
#include "src/utils/plane.h"
#include "src/utils/thread_utils.h"
#include "src/wp2/decode.h"
namespace WP2 {
class GlobalParams;
//------------------------------------------------------------------------------
struct Tile {
bool chunk_size_is_known = false; // True when the chunk size is decoded.
uint32_t chunk_size = 0; // Value is valid if chunk_size_is_known.
DataSource* input = nullptr; // Input data. Points to private_input
ExternalDataSource private_input; // if the whole chunk is available.
DataSource::DataHandle data_handle; // Keep the chunks of several tiles from
// the data source without copy.
Rectangle rect; // Tile bounds within frame (px, not padded).
bool output_is_yuv = false; // True if 'yuv_output' contains the pixels,
// false if 'rgb_output' does.
YUVPlane yuv_output; // Lossy output buffer view (padded).
ArgbBuffer rgb_output; // Lossless output buffer view (not padded).
uint32_t num_decoded_rows = 0; // For incremental decoding; the number of
// already decoded rows in this tile.
FilterBlockMap block_map; // Info (segment, bpp etc.) per block. Lossy only.
ProgressScale row_progress; // Advance by 1 for each decoded row.
void Clear();
void Draw(const WP2::DecoderConfig& config); // For debugging.
};
//------------------------------------------------------------------------------
struct TilesLayout {
uint32_t num_tiles_x = 0;
uint32_t num_tiles_y = 0;
uint32_t tile_width = 0; // Pixels, not padded.
uint32_t tile_height = 0;
Vector<Tile> tiles;
uint32_t num_assignable_tiles = 0; // Number of tiles with full input data.
uint32_t first_unassigned_tile_index = 0; // Next tile to assign a worker to.
uint32_t num_decoded_tiles = 0; // Total number of decoded tiles.
ThreadLock assignment_lock; // In case of concurrency.
// Returns the tile containing the pixel located at (x,y).
const Tile& GetTileAt(uint32_t x, uint32_t y) const;
// frame's global parameters (externally owned)
const GlobalParams* gparams = nullptr;
};
// Returns the number of tiles (per axis too if not null) depending on the
// 'frame_width' and 'frame_height' (in pixels, not padded).
uint32_t GetNumTiles(uint32_t frame_width, uint32_t frame_height,
uint32_t tile_width, uint32_t tile_height,
uint32_t* const num_tiles_x = nullptr,
uint32_t* const num_tiles_y = nullptr);
// Returns the tile area within the frame (in pixels, not padded).
// The specified 'tile_index' is ordered by rows, top-left being 0.
Rectangle GetTileRect(uint32_t frame_width, uint32_t frame_height,
uint32_t tile_width, uint32_t tile_height,
uint32_t tile_index);
// Assigns the 'tiles_layout' with the buffers split into a view per tile.
// 'rgb_output' and/or 'yuv_output' can be empty.
WP2Status GetTilesLayout(uint32_t frame_width, uint32_t frame_height,
uint32_t tile_width, uint32_t tile_height,
const ProgressRange& progress,
ArgbBuffer* const rgb_output,
YUVPlane* const yuv_output,
TilesLayout* const tiles_layout);
// Returns the maximum number of bytes that the chunk of a tile can occupy
// (without the chunk size header). 'tile_rect' in pixels, not padded.
uint32_t GetTileMaxNumBytes(uint32_t rgb_bit_depth, const GlobalParams& gparams,
const Rectangle& tile_rect);
//------------------------------------------------------------------------------
class TileDecoder : public WorkerBase {
public:
TileDecoder() = default;
TileDecoder(TileDecoder&&) = default;
// If this is 'self_assigning_' and there are assignable tiles left, assigns
// the next 'tile_' to this worker. Otherwise, set 'tile_' to null.
WP2Status TryAssignNextTile();
// As long as 'tile_' is not null, decode it and TryAssignNextTile().
WP2Status Execute() override;
// Decodes pixels as row-ordered raw samples.
WP2Status BypassTileDec();
protected:
// Decodes pixels as row-ordered raw samples.
WP2Status BypassTileDecRgb8b();
WP2Status BypassTileDecRgb10b();
WP2Status BypassTileDecYuv();
public:
const BitstreamFeatures* features_ = nullptr;
const DecoderConfig* config_ = nullptr;
const GlobalParams* gparams_ = nullptr;
TilesLayout* tiles_layout_ = nullptr; // Used to get next assignable tile.
Tile* tile_ = nullptr; // Currently assigned tile.
bool self_assigning_ = true; // If true tries to assign a new tile when done.
};
//------------------------------------------------------------------------------
// Instanciates and sets up a number of 'workers' depending on the number of
// tiles and threads.
WP2Status SetupWorkers(const BitstreamFeatures& features,
const DecoderConfig& config,
TilesLayout* const tiles_layout,
Vector<TileDecoder>* const workers);
// Skips global params and then calls SkipTiles.
WP2Status SkipGlobalParamsAndTiles(DataSource* const data_source,
const BitstreamFeatures& features,
const Rectangle& window);
// Skips all tiles fitting in 'window' from the 'data_source'.
WP2Status SkipTiles(const GlobalParams& gparams, DataSource* const data_source,
const BitstreamFeatures& features, const Rectangle& window);
//------------------------------------------------------------------------------
} // namespace WP2
#endif // WP2_DEC_TILE_DEC_H_