1 /* 2 * H.265 video codec. 3 * Copyright (c) 2013-2014 struktur AG, Dirk Farin <farin@struktur.de> 4 * 5 * This file is part of libde265. 6 * 7 * libde265 is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU Lesser General Public License as 9 * published by the Free Software Foundation, either version 3 of 10 * the License, or (at your option) any later version. 11 * 12 * libde265 is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public License 18 * along with libde265. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #ifndef DE265_IMAGE_H 22 #define DE265_IMAGE_H 23 24 #ifdef HAVE_CONFIG_H 25 #include <config.h> 26 #endif 27 28 #include <assert.h> 29 #include <stdint.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <memory> 33 #ifdef HAVE_STDBOOL_H 34 #include <stdbool.h> 35 #endif 36 37 #include "libde265/de265.h" 38 #include "libde265/sps.h" 39 #include "libde265/pps.h" 40 #include "libde265/motion.h" 41 #include "libde265/threads.h" 42 #include "libde265/slice.h" 43 #include "libde265/nal.h" 44 45 struct en265_encoder_context; 46 47 enum PictureState { 48 UnusedForReference, 49 UsedForShortTermReference, 50 UsedForLongTermReference 51 }; 52 53 54 /* TODO: 55 At INTEGRITY_DERIVED_FROM_FAULTY_REFERENCE images, we can check the SEI hash, whether 56 the output image is correct despite the faulty reference, and set the state back to correct. 57 */ 58 #define INTEGRITY_CORRECT 0 59 #define INTEGRITY_UNAVAILABLE_REFERENCE 1 60 #define INTEGRITY_NOT_DECODED 2 61 #define INTEGRITY_DECODING_ERRORS 3 62 #define INTEGRITY_DERIVED_FROM_FAULTY_REFERENCE 4 63 64 #define SEI_HASH_UNCHECKED 0 65 #define SEI_HASH_CORRECT 1 66 #define SEI_HASH_INCORRECT 2 67 68 #define TU_FLAG_NONZERO_COEFF (1<<7) 69 #define TU_FLAG_SPLIT_TRANSFORM_MASK 0x1F 70 71 #define DEBLOCK_FLAG_VERTI (1<<4) 72 #define DEBLOCK_FLAG_HORIZ (1<<5) 73 #define DEBLOCK_PB_EDGE_VERTI (1<<6) 74 #define DEBLOCK_PB_EDGE_HORIZ (1<<7) 75 #define DEBLOCK_BS_MASK 0x03 76 77 78 #define CTB_PROGRESS_NONE 0 79 #define CTB_PROGRESS_PREFILTER 1 80 #define CTB_PROGRESS_DEBLK_V 2 81 #define CTB_PROGRESS_DEBLK_H 3 82 #define CTB_PROGRESS_SAO 4 83 84 class decoder_context; 85 86 template <class DataUnit> class MetaDataArray 87 { 88 public: MetaDataArray()89 MetaDataArray() { data=NULL; data_size=0; log2unitSize=0; width_in_units=0; height_in_units=0; } ~MetaDataArray()90 ~MetaDataArray() { free(data); } 91 alloc(int w,int h,int _log2unitSize)92 LIBDE265_CHECK_RESULT bool alloc(int w,int h, int _log2unitSize) { 93 int size = w*h; 94 95 if (size != data_size) { 96 free(data); 97 data = (DataUnit*)malloc(size * sizeof(DataUnit)); 98 if (data == NULL) { 99 data_size = 0; 100 return false; 101 } 102 data_size = size; 103 } 104 105 width_in_units = w; 106 height_in_units = h; 107 108 log2unitSize = _log2unitSize; 109 110 return data != NULL; 111 } 112 clear()113 void clear() { 114 if (data) memset(data, 0, sizeof(DataUnit) * data_size); 115 } 116 get(int x,int y)117 const DataUnit& get(int x,int y) const { 118 int unitX = x>>log2unitSize; 119 int unitY = y>>log2unitSize; 120 121 assert(unitX >= 0 && unitX < width_in_units); 122 assert(unitY >= 0 && unitY < height_in_units); 123 124 return data[ unitX + unitY*width_in_units ]; 125 } 126 get(int x,int y)127 DataUnit& get(int x,int y) { 128 int unitX = x>>log2unitSize; 129 int unitY = y>>log2unitSize; 130 131 assert(unitX >= 0 && unitX < width_in_units); 132 assert(unitY >= 0 && unitY < height_in_units); 133 134 return data[ unitX + unitY*width_in_units ]; 135 } 136 set(int x,int y,const DataUnit & d)137 void set(int x,int y, const DataUnit& d) { 138 int unitX = x>>log2unitSize; 139 int unitY = y>>log2unitSize; 140 141 assert(unitX >= 0 && unitX < width_in_units); 142 assert(unitY >= 0 && unitY < height_in_units); 143 144 data[ unitX + unitY*width_in_units ] = d; 145 } 146 147 DataUnit& operator[](int idx) { return data[idx]; } 148 const DataUnit& operator[](int idx) const { return data[idx]; } 149 size()150 int size() const { return data_size; } 151 152 // private: 153 DataUnit* data; 154 int data_size; 155 int log2unitSize; 156 int width_in_units; 157 int height_in_units; 158 }; 159 160 #define SET_CB_BLK(x,y,log2BlkWidth, Field,value) \ 161 int cbX = x >> cb_info.log2unitSize; \ 162 int cbY = y >> cb_info.log2unitSize; \ 163 int width = 1 << (log2BlkWidth - cb_info.log2unitSize); \ 164 for (int cby=cbY;cby<cbY+width;cby++) \ 165 for (int cbx=cbX;cbx<cbX+width;cbx++) \ 166 { \ 167 cb_info[ cbx + cby*cb_info.width_in_units ].Field = value; \ 168 } 169 170 #define CLEAR_TB_BLK(x,y,log2BlkWidth) \ 171 int tuX = x >> tu_info.log2unitSize; \ 172 int tuY = y >> tu_info.log2unitSize; \ 173 int width = 1 << (log2BlkWidth - tu_info.log2unitSize); \ 174 for (int tuy=tuY;tuy<tuY+width;tuy++) \ 175 for (int tux=tuX;tux<tuX+width;tux++) \ 176 { \ 177 tu_info[ tux + tuy*tu_info.width_in_units ] = 0; \ 178 } 179 180 181 typedef struct { 182 uint16_t SliceAddrRS; 183 uint16_t SliceHeaderIndex; // index into array to slice header for this CTB 184 185 sao_info saoInfo; 186 bool deblock; // this CTB has to be deblocked 187 188 // The following flag helps to quickly check whether we have to 189 // check all conditions in the SAO filter or whether we can skip them. 190 bool has_pcm_or_cu_transquant_bypass; // pcm or transquant_bypass is used in this CTB 191 } CTB_info; 192 193 194 typedef struct { 195 uint8_t log2CbSize : 3; /* [0;6] (1<<log2CbSize) = 64 196 This is only set in the top-left corner of the CB. 197 The other values should be zero. 198 TODO: in the encoder, we have to clear to zero. 199 Used in deblocking and QP-scale decoding */ 200 uint8_t PartMode : 3; // (enum PartMode) [0;7] set only in top-left of CB 201 // Used for spatial merging candidates in current frame 202 // and for deriving interSplitFlag in decoding. 203 204 uint8_t ctDepth : 2; // [0:3]? (for CTB size 64: 0:64, 1:32, 2:16, 3:8) 205 // Used for decoding/encoding split_cu flag. 206 207 // --- byte boundary --- 208 uint8_t PredMode : 2; // (enum PredMode) [0;2] must be saved for past images 209 // Used in motion decoding. 210 uint8_t pcm_flag : 1; // Stored for intra-prediction / SAO 211 uint8_t cu_transquant_bypass : 1; // Stored for SAO 212 // note: 4 bits left 213 214 // --- byte boundary --- 215 int8_t QP_Y; // Stored for QP prediction 216 217 } CB_ref_info; 218 219 220 221 222 struct de265_image { 223 de265_image(); 224 ~de265_image(); 225 226 227 de265_error alloc_image(int w,int h, enum de265_chroma c, 228 std::shared_ptr<const seq_parameter_set> sps, 229 bool allocMetadata, 230 decoder_context* dctx, 231 //class encoder_context* ectx, 232 de265_PTS pts, void* user_data, 233 bool useCustomAllocFunctions); 234 235 //de265_error alloc_encoder_data(const seq_parameter_set* sps); 236 is_allocatedde265_image237 bool is_allocated() const { return pixels[0] != NULL; } 238 239 void release(); 240 set_headersde265_image241 void set_headers(std::shared_ptr<video_parameter_set> _vps, 242 std::shared_ptr<seq_parameter_set> _sps, 243 std::shared_ptr<pic_parameter_set> _pps) { 244 vps = _vps; 245 sps = _sps; 246 pps = _pps; 247 } 248 249 void fill_image(int y,int u,int v); 250 de265_error copy_image(const de265_image* src); 251 void copy_lines_from(const de265_image* src, int first, int end); 252 void exchange_pixel_data_with(de265_image&); 253 get_IDde265_image254 uint32_t get_ID() const { return ID; } 255 256 get_image_planede265_image257 /* */ uint8_t* get_image_plane(int cIdx) { return pixels[cIdx]; } get_image_planede265_image258 const uint8_t* get_image_plane(int cIdx) const { return pixels[cIdx]; } 259 260 void set_image_plane(int cIdx, uint8_t* mem, int stride, void *userdata); 261 get_image_plane_at_posde265_image262 uint8_t* get_image_plane_at_pos(int cIdx, int xpos,int ypos) 263 { 264 int stride = get_image_stride(cIdx); 265 return pixels[cIdx] + xpos + ypos*stride; 266 } 267 268 269 /// xpos;ypos in actual plane resolution 270 template <class pixel_t> get_image_plane_at_pos_NEWde265_image271 pixel_t* get_image_plane_at_pos_NEW(int cIdx, int xpos,int ypos) 272 { 273 int stride = get_image_stride(cIdx); 274 return (pixel_t*)(pixels[cIdx] + (xpos + ypos*stride)*sizeof(pixel_t)); 275 } 276 get_image_plane_at_posde265_image277 const uint8_t* get_image_plane_at_pos(int cIdx, int xpos,int ypos) const 278 { 279 int stride = get_image_stride(cIdx); 280 return pixels[cIdx] + xpos + ypos*stride; 281 } 282 get_image_plane_at_pos_any_depthde265_image283 void* get_image_plane_at_pos_any_depth(int cIdx, int xpos,int ypos) 284 { 285 int stride = get_image_stride(cIdx); 286 return pixels[cIdx] + ((xpos + ypos*stride) << bpp_shift[cIdx]); 287 } 288 get_image_plane_at_pos_any_depthde265_image289 const void* get_image_plane_at_pos_any_depth(int cIdx, int xpos,int ypos) const 290 { 291 int stride = get_image_stride(cIdx); 292 return pixels[cIdx] + ((xpos + ypos*stride) << bpp_shift[cIdx]); 293 } 294 295 /* Number of pixels in one row (not number of bytes). 296 */ get_image_stridede265_image297 int get_image_stride(int cIdx) const 298 { 299 if (cIdx==0) return stride; 300 else return chroma_stride; 301 } 302 get_luma_stridede265_image303 int get_luma_stride() const { return stride; } get_chroma_stridede265_image304 int get_chroma_stride() const { return chroma_stride; } 305 306 int get_width (int cIdx=0) const { return cIdx==0 ? width : chroma_width; } 307 int get_height(int cIdx=0) const { return cIdx==0 ? height : chroma_height; } 308 get_chroma_formatde265_image309 enum de265_chroma get_chroma_format() const { return chroma_format; } 310 get_bit_depthde265_image311 int get_bit_depth(int cIdx) const { 312 if (cIdx==0) return sps->BitDepth_Y; 313 else return sps->BitDepth_C; 314 } 315 get_bytes_per_pixelde265_image316 int get_bytes_per_pixel(int cIdx) const { 317 return (get_bit_depth(cIdx)+7)/8; 318 } 319 high_bit_depthde265_image320 bool high_bit_depth(int cIdx) const { 321 return get_bit_depth(cIdx)>8; 322 } 323 can_be_releasedde265_image324 bool can_be_released() const { return PicOutputFlag==false && PicState==UnusedForReference; } 325 326 add_slice_segment_headerde265_image327 void add_slice_segment_header(slice_segment_header* shdr) { 328 shdr->slice_index = slices.size(); 329 slices.push_back(shdr); 330 } 331 332 333 bool available_zscan(int xCurr,int yCurr, int xN,int yN) const; 334 335 bool available_pred_blk(int xC,int yC, int nCbS, 336 int xP, int yP, int nPbW, int nPbH, int partIdx, 337 int xN,int yN) const; 338 339 340 static de265_image_allocation default_image_allocation; 341 printBlkde265_image342 void printBlk(const char* title, int x0,int y0,int blkSize,int cIdx) const { 343 ::printBlk(title, get_image_plane_at_pos(cIdx,x0,y0), 344 blkSize, get_image_stride(cIdx)); 345 } 346 347 private: 348 uint32_t ID; 349 static uint32_t s_next_image_ID; 350 351 uint8_t* pixels[3]; 352 uint8_t bpp_shift[3]; // 0 for 8 bit, 1 for 16 bit 353 354 enum de265_chroma chroma_format; 355 356 int width, height; // size in luma pixels 357 358 int chroma_width, chroma_height; 359 int stride, chroma_stride; 360 361 public: 362 uint8_t BitDepth_Y, BitDepth_C; 363 uint8_t SubWidthC, SubHeightC; 364 std::vector<slice_segment_header*> slices; 365 366 public: 367 368 // --- conformance cropping window --- 369 370 uint8_t* pixels_confwin[3]; // pointer to pixels in the conformance window 371 372 int width_confwin, height_confwin; 373 int chroma_width_confwin, chroma_height_confwin; 374 375 // --- decoding info --- 376 377 // If PicOutputFlag==false && PicState==UnusedForReference, image buffer is free. 378 379 int picture_order_cnt_lsb; 380 int PicOrderCntVal; 381 enum PictureState PicState; 382 bool PicOutputFlag; 383 384 int32_t removed_at_picture_id; 385 get_vpsde265_image386 const video_parameter_set& get_vps() const { return *vps; } get_spsde265_image387 const seq_parameter_set& get_sps() const { return *sps; } get_ppsde265_image388 const pic_parameter_set& get_pps() const { return *pps; } 389 has_vpsde265_image390 bool has_vps() const { return (bool)vps; } has_spsde265_image391 bool has_sps() const { return (bool)sps; } has_ppsde265_image392 bool has_pps() const { return (bool)pps; } 393 get_shared_spsde265_image394 std::shared_ptr<const seq_parameter_set> get_shared_sps() { return sps; } 395 396 //std::shared_ptr<const seq_parameter_set> get_shared_sps() const { return sps; } 397 //std::shared_ptr<const pic_parameter_set> get_shared_pps() const { return pps; } 398 399 decoder_context* decctx; 400 //class encoder_context* encctx; 401 number_of_ctbsde265_image402 int number_of_ctbs() const { return ctb_info.size(); } 403 404 private: 405 // The image also keeps a reference to VPS/SPS/PPS, because when decoding is delayed, 406 // the currently active parameter sets in the decctx might already have been replaced 407 // with new parameters. 408 std::shared_ptr<const video_parameter_set> vps; 409 std::shared_ptr<const seq_parameter_set> sps; // the SPS used for decoding this image 410 std::shared_ptr<const pic_parameter_set> pps; // the PPS used for decoding this image 411 412 MetaDataArray<CTB_info> ctb_info; 413 MetaDataArray<CB_ref_info> cb_info; 414 MetaDataArray<PBMotion> pb_info; 415 MetaDataArray<uint8_t> intraPredMode; 416 MetaDataArray<uint8_t> intraPredModeC; 417 MetaDataArray<uint8_t> tu_info; 418 MetaDataArray<uint8_t> deblk_info; 419 420 public: 421 // --- meta information --- 422 423 de265_PTS pts; 424 void* user_data; 425 void* plane_user_data[3]; // this is logically attached to the pixel data pointers 426 de265_image_allocation image_allocation_functions; // the functions used for memory allocation 427 428 /* 429 void (*encoder_image_release_func)(en265_encoder_context*, 430 de265_image*, 431 void* userdata); 432 */ 433 434 uint8_t integrity; /* Whether an error occured while the image was decoded. 435 When generated, this is initialized to INTEGRITY_CORRECT, 436 and changed on decoding errors. 437 */ 438 bool sei_hash_check_result; 439 440 nal_header nal_hdr; 441 442 // --- multi core --- 443 444 de265_progress_lock* ctb_progress; // ctb_info_size 445 mark_all_CTB_progressde265_image446 void mark_all_CTB_progress(int progress) { 447 for (int i=0;i<ctb_info.data_size;i++) { 448 ctb_progress[i].set_progress(progress); 449 } 450 } 451 452 453 void thread_start(int nThreads); 454 void thread_run(const thread_task*); 455 void thread_blocks(); 456 void thread_unblocks(); 457 /* NOTE: you should not access any data in the thread_task after 458 calling this, as this function may unlock other threads that 459 will push this image to the output queue and free all decoder data. */ 460 void thread_finishes(const thread_task*); 461 462 void wait_for_progress(thread_task* task, int ctbx,int ctby, int progress); 463 void wait_for_progress(thread_task* task, int ctbAddrRS, int progress); 464 465 void wait_for_completion(); // block until image is decoded by background threads 466 bool debug_is_completed() const; num_threads_activede265_image467 int num_threads_active() const { return nThreadsRunning + nThreadsBlocked; } // for debug only 468 469 //private: 470 int nThreadsQueued; 471 int nThreadsRunning; 472 int nThreadsBlocked; 473 int nThreadsFinished; 474 int nThreadsTotal; 475 476 // ALIGNED_8(de265_sync_int tasks_pending); // number of tasks pending to complete decoding 477 de265_mutex mutex; 478 de265_cond finished_cond; 479 480 public: 481 482 /* Clear all CTB/CB/PB decoding data of this image. 483 All CTB's processing states are set to 'unprocessed'. 484 */ 485 void clear_metadata(); 486 487 488 // --- CB metadata access --- 489 set_pred_modede265_image490 void set_pred_mode(int x,int y, int log2BlkWidth, enum PredMode mode) 491 { 492 SET_CB_BLK(x,y,log2BlkWidth, PredMode, mode); 493 } 494 fill_pred_modede265_image495 void fill_pred_mode(enum PredMode mode) 496 { 497 for (int i=0;i<cb_info.data_size;i++) 498 { cb_info[i].PredMode = MODE_INTRA; } 499 } 500 get_pred_modede265_image501 enum PredMode get_pred_mode(int x,int y) const 502 { 503 return (enum PredMode)cb_info.get(x,y).PredMode; 504 } 505 get_cu_skip_flagde265_image506 uint8_t get_cu_skip_flag(int x,int y) const 507 { 508 return get_pred_mode(x,y)==MODE_SKIP; 509 } 510 511 void set_pcm_flag(int x,int y, int log2BlkWidth, uint8_t value=1) 512 { 513 SET_CB_BLK(x,y,log2BlkWidth, pcm_flag, value); 514 515 // TODO: in the encoder, we somewhere have to clear this 516 ctb_info.get(x,y).has_pcm_or_cu_transquant_bypass = true; 517 } 518 get_pcm_flagde265_image519 int get_pcm_flag(int x,int y) const 520 { 521 return cb_info.get(x,y).pcm_flag; 522 } 523 524 void set_cu_transquant_bypass(int x,int y, int log2BlkWidth, uint8_t value=1) 525 { 526 SET_CB_BLK(x,y,log2BlkWidth, cu_transquant_bypass, value); 527 528 // TODO: in the encoder, we somewhere have to clear this 529 ctb_info.get(x,y).has_pcm_or_cu_transquant_bypass = true; 530 } 531 get_cu_transquant_bypassde265_image532 int get_cu_transquant_bypass(int x,int y) const 533 { 534 return cb_info.get(x,y).cu_transquant_bypass; 535 } 536 set_log2CbSizede265_image537 void set_log2CbSize(int x0, int y0, int log2CbSize, bool fill) 538 { 539 // In theory, we could assume that remaining cb_info blocks are initialized to zero. 540 // But in corrupted streams, slices may overlap and set contradicting log2CbSizes. 541 // We also need this for encoding. 542 if (fill) { 543 SET_CB_BLK(x0,y0,log2CbSize, log2CbSize, 0); 544 } 545 546 cb_info.get(x0,y0).log2CbSize = log2CbSize; 547 } 548 get_log2CbSizede265_image549 int get_log2CbSize(int x0, int y0) const 550 { 551 return (enum PredMode)cb_info.get(x0,y0).log2CbSize; 552 } 553 554 // coordinates in CB units get_log2CbSize_cbUnitsde265_image555 int get_log2CbSize_cbUnits(int xCb, int yCb) const 556 { 557 return (enum PredMode)cb_info[ xCb + yCb*cb_info.width_in_units ].log2CbSize; 558 } 559 set_PartModede265_image560 void set_PartMode(int x,int y, enum PartMode mode) 561 { 562 cb_info.get(x,y).PartMode = mode; 563 } 564 get_PartModede265_image565 enum PartMode get_PartMode(int x,int y) const 566 { 567 return (enum PartMode)cb_info.get(x,y).PartMode; 568 } 569 set_ctDepthde265_image570 void set_ctDepth(int x,int y, int log2BlkWidth, int depth) 571 { 572 SET_CB_BLK(x,y,log2BlkWidth, ctDepth, depth); 573 } 574 get_ctDepthde265_image575 int get_ctDepth(int x,int y) const 576 { 577 return cb_info.get(x,y).ctDepth; 578 } 579 set_QPYde265_image580 void set_QPY(int x,int y, int log2BlkWidth, int QP_Y) 581 { 582 SET_CB_BLK (x, y, log2BlkWidth, QP_Y, QP_Y); 583 } 584 get_QPYde265_image585 int get_QPY(int x0,int y0) const 586 { 587 return cb_info.get(x0,y0).QP_Y; 588 } 589 590 // --- TU metadata access --- 591 set_split_transform_flagde265_image592 void set_split_transform_flag(int x0,int y0,int trafoDepth) 593 { 594 tu_info.get(x0,y0) |= (1<<trafoDepth); 595 } 596 clear_split_transform_flagsde265_image597 void clear_split_transform_flags(int x0,int y0,int log2CbSize) 598 { 599 CLEAR_TB_BLK (x0,y0, log2CbSize); 600 } 601 get_split_transform_flagde265_image602 int get_split_transform_flag(int x0,int y0,int trafoDepth) const 603 { 604 return (tu_info.get(x0,y0) & (1<<trafoDepth)); 605 } 606 set_nonzero_coefficientde265_image607 void set_nonzero_coefficient(int x,int y, int log2TrafoSize) 608 { 609 const int tuX = x >> tu_info.log2unitSize; 610 const int tuY = y >> tu_info.log2unitSize; 611 const int width = 1 << (log2TrafoSize - tu_info.log2unitSize); 612 613 for (int tuy=tuY;tuy<tuY+width;tuy++) 614 for (int tux=tuX;tux<tuX+width;tux++) 615 { 616 tu_info[ tux + tuy*tu_info.width_in_units ] |= TU_FLAG_NONZERO_COEFF; 617 } 618 } 619 get_nonzero_coefficientde265_image620 int get_nonzero_coefficient(int x,int y) const 621 { 622 return tu_info.get(x,y) & TU_FLAG_NONZERO_COEFF; 623 } 624 625 626 // --- intraPredMode metadata access --- 627 get_IntraPredModede265_image628 enum IntraPredMode get_IntraPredMode(int x,int y) const 629 { 630 return (enum IntraPredMode)intraPredMode.get(x,y); 631 } 632 get_IntraPredMode_atIndexde265_image633 enum IntraPredMode get_IntraPredMode_atIndex(int idx) const 634 { 635 return (enum IntraPredMode)intraPredMode[idx]; 636 } 637 set_IntraPredModede265_image638 void set_IntraPredMode(int PUidx,int log2blkSize, enum IntraPredMode mode) 639 { 640 int pbSize = 1<<(log2blkSize - intraPredMode.log2unitSize); 641 642 for (int y=0;y<pbSize;y++) 643 for (int x=0;x<pbSize;x++) 644 intraPredMode[PUidx + x + y*intraPredMode.width_in_units] = mode; 645 } 646 set_IntraPredModede265_image647 void set_IntraPredMode(int x0,int y0,int log2blkSize, 648 enum IntraPredMode mode) 649 { 650 int pbSize = 1<<(log2blkSize - intraPredMode.log2unitSize); 651 int PUidx = (x0>>sps->Log2MinPUSize) + (y0>>sps->Log2MinPUSize)*sps->PicWidthInMinPUs; 652 653 for (int y=0;y<pbSize;y++) 654 for (int x=0;x<pbSize;x++) { 655 assert(x < sps->PicWidthInMinPUs); 656 assert(y < sps->PicHeightInMinPUs); 657 658 int idx = PUidx + x + y*intraPredMode.width_in_units; 659 assert(idx<intraPredMode.data_size); 660 intraPredMode[idx] = mode; 661 } 662 } 663 664 get_IntraPredModeCde265_image665 enum IntraPredMode get_IntraPredModeC(int x,int y) const 666 { 667 return (enum IntraPredMode)(intraPredModeC.get(x,y) & 0x3f); 668 } 669 is_IntraPredModeC_Mode4de265_image670 bool is_IntraPredModeC_Mode4(int x,int y) const 671 { 672 return intraPredModeC.get(x,y) & 0x80; 673 } 674 set_IntraPredModeCde265_image675 void set_IntraPredModeC(int x0,int y0,int log2blkSize, enum IntraPredMode mode, 676 bool is_mode4) 677 { 678 uint8_t combinedValue = mode; 679 if (is_mode4) combinedValue |= 0x80; 680 681 int pbSize = 1<<(log2blkSize - intraPredMode.log2unitSize); 682 int PUidx = (x0>>sps->Log2MinPUSize) + (y0>>sps->Log2MinPUSize)*sps->PicWidthInMinPUs; 683 684 for (int y=0;y<pbSize;y++) 685 for (int x=0;x<pbSize;x++) { 686 assert(x<sps->PicWidthInMinPUs); 687 assert(y<sps->PicHeightInMinPUs); 688 689 int idx = PUidx + x + y*intraPredModeC.width_in_units; 690 assert(idx<intraPredModeC.data_size); 691 intraPredModeC[idx] = combinedValue; 692 } 693 } 694 695 696 /* 697 // NOTE: encoder only 698 void set_ChromaIntraPredMode(int x,int y,int log2BlkWidth, enum IntraChromaPredMode mode) 699 { 700 SET_CB_BLK (x, y, log2BlkWidth, intra_chroma_pred_mode, mode); 701 } 702 703 // NOTE: encoder only 704 enum IntraChromaPredMode get_ChromaIntraPredMode(int x,int y) const 705 { 706 return (enum IntraChromaPredMode)(cb_info.get(x,y).intra_chroma_pred_mode); 707 } 708 */ 709 710 // --- CTB metadata access --- 711 712 // address of first CTB in slice set_SliceAddrRSde265_image713 void set_SliceAddrRS(int ctbX, int ctbY, int SliceAddrRS) 714 { 715 int idx = ctbX + ctbY*ctb_info.width_in_units; 716 ctb_info[idx].SliceAddrRS = SliceAddrRS; 717 } 718 get_SliceAddrRSde265_image719 int get_SliceAddrRS(int ctbX, int ctbY) const 720 { 721 return ctb_info[ctbX + ctbY*ctb_info.width_in_units].SliceAddrRS; 722 } 723 get_SliceAddrRS_atCtbRSde265_image724 int get_SliceAddrRS_atCtbRS(int ctbRS) const 725 { 726 return ctb_info[ctbRS].SliceAddrRS; 727 } 728 729 set_SliceHeaderIndexde265_image730 void set_SliceHeaderIndex(int x, int y, int SliceHeaderIndex) 731 { 732 ctb_info.get(x,y).SliceHeaderIndex = SliceHeaderIndex; 733 } 734 get_SliceHeaderIndexde265_image735 int get_SliceHeaderIndex(int x, int y) const 736 { 737 return ctb_info.get(x,y).SliceHeaderIndex; 738 } 739 get_SliceHeaderIndexCtbde265_image740 int get_SliceHeaderIndexCtb(int ctbX, int ctbY) const 741 { 742 return ctb_info[ctbX + ctbY*ctb_info.width_in_units].SliceHeaderIndex; 743 } 744 get_SliceHeaderIndex_atIndexde265_image745 int get_SliceHeaderIndex_atIndex(int ctb) const 746 { 747 return ctb_info[ctb].SliceHeaderIndex; 748 } 749 is_SliceHeader_availablede265_image750 bool is_SliceHeader_available(int x,int y) const 751 { 752 int idx = ctb_info.get(x,y).SliceHeaderIndex; 753 return idx >= 0 && idx < slices.size(); 754 } 755 get_SliceHeaderde265_image756 slice_segment_header* get_SliceHeader(int x, int y) 757 { 758 int idx = get_SliceHeaderIndex(x,y); 759 if (idx >= slices.size()) { return NULL; } 760 return slices[idx]; 761 } 762 get_SliceHeaderCtbde265_image763 slice_segment_header* get_SliceHeaderCtb(int ctbX, int ctbY) 764 { 765 int idx = get_SliceHeaderIndexCtb(ctbX,ctbY); 766 if (idx >= slices.size()) { return NULL; } 767 return slices[idx]; 768 } 769 get_SliceHeaderCtbde265_image770 const slice_segment_header* get_SliceHeaderCtb(int ctbX, int ctbY) const 771 { 772 int idx = get_SliceHeaderIndexCtb(ctbX,ctbY); 773 if (idx >= slices.size()) { return NULL; } 774 return slices[idx]; 775 } 776 set_sao_infode265_image777 void set_sao_info(int ctbX,int ctbY,const sao_info* saoinfo) 778 { 779 sao_info* sao = &ctb_info[ctbX + ctbY*ctb_info.width_in_units].saoInfo; 780 781 memcpy(sao, 782 saoinfo, 783 sizeof(sao_info)); 784 } 785 get_sao_infode265_image786 const sao_info* get_sao_info(int ctbX,int ctbY) const 787 { 788 return &ctb_info[ctbX + ctbY*ctb_info.width_in_units].saoInfo; 789 } 790 791 set_CtbDeblockFlagde265_image792 void set_CtbDeblockFlag(int ctbX, int ctbY, bool flag) 793 { 794 int idx = ctbX + ctbY*ctb_info.width_in_units; 795 ctb_info[idx].deblock = flag; 796 } 797 get_CtbDeblockFlagde265_image798 bool get_CtbDeblockFlag(int ctbX, int ctbY) const 799 { 800 return ctb_info[ctbX + ctbY*ctb_info.width_in_units].deblock; 801 } 802 803 get_CTB_has_pcm_or_cu_transquant_bypassde265_image804 bool get_CTB_has_pcm_or_cu_transquant_bypass(int ctbX,int ctbY) const 805 { 806 int idx = ctbX + ctbY*ctb_info.width_in_units; 807 return ctb_info[idx].has_pcm_or_cu_transquant_bypass; 808 } 809 810 811 812 // --- DEBLK metadata access --- 813 get_deblk_widthde265_image814 int get_deblk_width() const { return deblk_info.width_in_units; } get_deblk_heightde265_image815 int get_deblk_height() const { return deblk_info.height_in_units; } 816 set_deblk_flagsde265_image817 void set_deblk_flags(int x0,int y0, uint8_t flags) 818 { 819 const int xd = x0/4; 820 const int yd = y0/4; 821 822 if (xd<deblk_info.width_in_units && 823 yd<deblk_info.height_in_units) { 824 deblk_info[xd + yd*deblk_info.width_in_units] |= flags; 825 } 826 } 827 get_deblk_flagsde265_image828 uint8_t get_deblk_flags(int x0,int y0) const 829 { 830 const int xd = x0/4; 831 const int yd = y0/4; 832 833 return deblk_info[xd + yd*deblk_info.width_in_units]; 834 } 835 set_deblk_bSde265_image836 void set_deblk_bS(int x0,int y0, uint8_t bS) 837 { 838 uint8_t* data = &deblk_info[x0/4 + y0/4*deblk_info.width_in_units]; 839 *data &= ~DEBLOCK_BS_MASK; 840 *data |= bS; 841 } 842 get_deblk_bSde265_image843 uint8_t get_deblk_bS(int x0,int y0) const 844 { 845 return deblk_info[x0/4 + y0/4*deblk_info.width_in_units] & DEBLOCK_BS_MASK; 846 } 847 848 849 // --- PB metadata access --- 850 get_mv_infode265_image851 const PBMotion& get_mv_info(int x,int y) const 852 { 853 return pb_info.get(x,y); 854 } 855 856 void set_mv_info(int x,int y, int nPbW,int nPbH, const PBMotion& mv); 857 858 // --- value logging --- 859 860 void printBlk(int x0,int y0, int cIdx, int log2BlkSize); 861 }; 862 863 864 #endif 865