~ubuntu-branches/ubuntu/wily/libde265/wily

« back to all changes in this revision

Viewing changes to libde265/image.h

  • Committer: Package Import Robot
  • Author(s): Joachim Bauch
  • Date: 2015-07-16 11:07:46 UTC
  • mfrom: (2.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20150716110746-76vsv24j3yux7tnu
Tags: 1.0.2-1
* Imported Upstream version 1.0.2
* Added new files to copyright information.
* Only export decoder API and update symbols for new version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
#include <stdbool.h>
34
34
#endif
35
35
#include "libde265/de265.h"
 
36
#include "libde265/en265.h"
36
37
#include "libde265/sps.h"
37
38
#include "libde265/pps.h"
38
39
#include "libde265/motion.h"
40
41
#include "libde265/slice.h"
41
42
#include "libde265/nal.h"
42
43
 
43
 
 
44
44
enum PictureState {
45
45
  UnusedForReference,
46
46
  UsedForShortTermReference,
78
78
#define CTB_PROGRESS_DEBLK_H   3
79
79
#define CTB_PROGRESS_SAO       4
80
80
 
 
81
class decoder_context;
 
82
 
81
83
template <class DataUnit> class MetaDataArray
82
84
{
83
85
 public:
84
86
  MetaDataArray() { data=NULL; data_size=0; log2unitSize=0; width_in_units=0; height_in_units=0; }
85
87
  ~MetaDataArray() { free(data); }
86
88
 
87
 
  bool alloc(int w,int h, int _log2unitSize) {
 
89
  LIBDE265_CHECK_RESULT bool alloc(int w,int h, int _log2unitSize) {
88
90
    int size = w*h;
89
91
 
90
92
    if (size != data_size) {
91
93
      free(data);
92
94
      data = (DataUnit*)malloc(size * sizeof(DataUnit));
 
95
      if (data == NULL) {
 
96
        data_size = 0;
 
97
        return false;
 
98
      }
93
99
      data_size = size;
94
 
      width_in_units = w;
95
 
      height_in_units = h;
96
100
    }
97
101
 
 
102
    width_in_units = w;
 
103
    height_in_units = h;
 
104
 
98
105
    log2unitSize = _log2unitSize;
99
106
 
100
107
    return data != NULL;
108
115
    int unitX = x>>log2unitSize;
109
116
    int unitY = y>>log2unitSize;
110
117
 
 
118
    assert(unitX >= 0 && unitX < width_in_units);
 
119
    assert(unitY >= 0 && unitY < height_in_units);
 
120
 
111
121
    return data[ unitX + unitY*width_in_units ];
112
122
  }
113
123
 
115
125
    int unitX = x>>log2unitSize;
116
126
    int unitY = y>>log2unitSize;
117
127
 
 
128
    assert(unitX >= 0 && unitX < width_in_units);
 
129
    assert(unitY >= 0 && unitY < height_in_units);
 
130
 
118
131
    return data[ unitX + unitY*width_in_units ];
119
132
  }
120
133
 
122
135
    int unitX = x>>log2unitSize;
123
136
    int unitY = y>>log2unitSize;
124
137
 
 
138
    assert(unitX >= 0 && unitX < width_in_units);
 
139
    assert(unitY >= 0 && unitY < height_in_units);
 
140
 
125
141
    data[ unitX + unitY*width_in_units ] = d;
126
142
  }
127
143
 
128
144
  DataUnit& operator[](int idx) { return data[idx]; }
129
145
  const DataUnit& operator[](int idx) const { return data[idx]; }
130
146
 
 
147
  int size() const { return data_size; }
 
148
 
131
149
  // private:
132
150
  DataUnit* data;
133
151
  int data_size;
146
164
        cb_info[ cbx + cby*cb_info.width_in_units ].Field = value;  \
147
165
      }
148
166
 
 
167
#define CLEAR_TB_BLK(x,y,log2BlkWidth)              \
 
168
  int tuX = x >> tu_info.log2unitSize; \
 
169
  int tuY = y >> tu_info.log2unitSize; \
 
170
  int width = 1 << (log2BlkWidth - tu_info.log2unitSize);           \
 
171
  for (int tuy=tuY;tuy<tuY+width;tuy++)                             \
 
172
    for (int tux=tuX;tux<tuX+width;tux++)                           \
 
173
      {                                                             \
 
174
        tu_info[ tux + tuy*tu_info.width_in_units ] = 0;  \
 
175
      }
 
176
 
149
177
 
150
178
typedef struct {
151
179
  uint16_t SliceAddrRS;
153
181
 
154
182
  sao_info saoInfo;
155
183
  bool     deblock;         // this CTB has to be deblocked
156
 
  bool     has_pcm;         // pcm is used in this CTB
157
 
  bool     has_cu_transquant_bypass; // transquant_bypass is used in this CTB
 
184
 
 
185
  // The following flag helps to quickly check whether we have to
 
186
  // check all conditions in the SAO filter or whether we can skip them.
 
187
  bool     has_pcm_or_cu_transquant_bypass; // pcm or transquant_bypass is used in this CTB
158
188
} CTB_info;
159
189
 
160
190
 
161
191
typedef struct {
162
 
  uint8_t log2CbSize : 3;   // [0;6] (1<<log2CbSize) = 64
 
192
  uint8_t log2CbSize : 3;   /* [0;6] (1<<log2CbSize) = 64
 
193
                               This is only set in the top-left corner of the CB.
 
194
                               The other values should be zero.
 
195
                               TODO: in the encoder, we have to clear to zero.
 
196
                               Used in deblocking and QP-scale decoding */
163
197
  uint8_t PartMode : 3;     // (enum PartMode)  [0;7] set only in top-left of CB
164
 
                            // TODO: could be removed if prediction-block-boundaries would be
165
 
                            // set during decoding
166
 
  uint8_t ctDepth : 2;      // [0:3]? (0:64, 1:32, 2:16, 3:8)
 
198
                            // Used for spatial merging candidates in current frame
 
199
                            // and for deriving interSplitFlag in decoding.
 
200
 
 
201
  uint8_t ctDepth : 2;      // [0:3]? (for CTB size 64: 0:64, 1:32, 2:16, 3:8)
 
202
                            // Used for decoding/encoding split_cu flag.
 
203
 
 
204
  // --- byte boundary ---
167
205
  uint8_t PredMode : 2;     // (enum PredMode)  [0;2] must be saved for past images
168
 
  uint8_t pcm_flag : 1;     //
169
 
  uint8_t cu_transquant_bypass : 1;
170
 
 
171
 
  int8_t  QP_Y;
172
 
 
173
 
  // uint8_t pcm_flag;  // TODO
 
206
                            // Used in motion decoding.
 
207
  uint8_t pcm_flag : 1;     // Stored for intra-prediction / SAO
 
208
  uint8_t cu_transquant_bypass : 1; // Stored for SAO
 
209
  // note: 4 bits left
 
210
 
 
211
  // --- byte boundary ---
 
212
  int8_t  QP_Y;  // Stored for QP prediction
 
213
 
174
214
} CB_ref_info;
175
215
 
176
216
 
177
217
typedef struct {
178
 
  PredVectorInfo mvi; // TODO: this can be done in 16x16 grid
 
218
  MotionVectorSpec mv; // TODO: this can be done in 16x16 grid
179
219
} PB_ref_info;
180
220
 
 
221
// intraPredMode:   Used for determining scanIdx when decoding/encoding coefficients.
 
222
 
181
223
 
182
224
 
183
225
struct de265_image {
185
227
  ~de265_image();
186
228
 
187
229
 
188
 
  de265_error alloc_image(int w,int h, enum de265_chroma c, const seq_parameter_set* sps,
189
 
                          bool allocMetadata, decoder_context* ctx, de265_PTS pts, void* user_data,
190
 
                          bool isOutputImage);
 
230
  de265_error alloc_image(int w,int h, enum de265_chroma c,
 
231
                          const seq_parameter_set* sps,
 
232
                          bool allocMetadata,
 
233
                          decoder_context* dctx,
 
234
                          class encoder_context* ectx,
 
235
                          de265_PTS pts, void* user_data,
 
236
                          bool useCustomAllocFunctions);
 
237
 
 
238
  //de265_error alloc_encoder_data(const seq_parameter_set* sps);
191
239
 
192
240
  bool is_allocated() const { return pixels[0] != NULL; }
193
241
 
212
260
    return pixels[cIdx] + xpos + ypos*stride;
213
261
  }
214
262
 
 
263
 
 
264
  /// xpos;ypos in actual plane resolution
 
265
  template <class pixel_t>
 
266
  pixel_t* get_image_plane_at_pos_NEW(int cIdx, int xpos,int ypos)
 
267
  {
 
268
    int stride = get_image_stride(cIdx);
 
269
    return (pixel_t*)(pixels[cIdx] + (xpos + ypos*stride)*sizeof(pixel_t));
 
270
  }
 
271
 
215
272
  const uint8_t* get_image_plane_at_pos(int cIdx, int xpos,int ypos) const
216
273
  {
217
274
    int stride = get_image_stride(cIdx);
218
275
    return pixels[cIdx] + xpos + ypos*stride;
219
276
  }
220
277
 
 
278
  void* get_image_plane_at_pos_any_depth(int cIdx, int xpos,int ypos)
 
279
  {
 
280
    int stride = get_image_stride(cIdx);
 
281
    return pixels[cIdx] + ((xpos + ypos*stride) << bpp_shift[cIdx]);
 
282
  }
 
283
 
 
284
  const void* get_image_plane_at_pos_any_depth(int cIdx, int xpos,int ypos) const
 
285
  {
 
286
    int stride = get_image_stride(cIdx);
 
287
    return pixels[cIdx] + ((xpos + ypos*stride) << bpp_shift[cIdx]);
 
288
  }
 
289
 
 
290
  /* Number of pixels in one row (not number of bytes).
 
291
   */
221
292
  int get_image_stride(int cIdx) const
222
293
  {
223
294
    if (cIdx==0) return stride;
232
303
 
233
304
  enum de265_chroma get_chroma_format() const { return chroma_format; }
234
305
 
 
306
  int get_bit_depth(int cIdx) const {
 
307
    if (cIdx==0) return sps.BitDepth_Y;
 
308
    else         return sps.BitDepth_C;
 
309
  }
 
310
 
 
311
  int get_bytes_per_pixel(int cIdx) const {
 
312
    return (get_bit_depth(cIdx)+7)/8;
 
313
  }
 
314
 
 
315
  bool high_bit_depth(int cIdx) const {
 
316
    return get_bit_depth(cIdx)>8;
 
317
  }
235
318
 
236
319
  bool can_be_released() const { return PicOutputFlag==false && PicState==UnusedForReference; }
237
320
 
251
334
 
252
335
  static de265_image_allocation default_image_allocation;
253
336
 
 
337
  void printBlk(const char* title, int x0,int y0,int blkSize,int cIdx) const {
 
338
    ::printBlk(title, get_image_plane_at_pos(cIdx,x0,y0),
 
339
               blkSize, get_image_stride(cIdx));
 
340
  }
 
341
 
254
342
private:
255
343
  uint32_t ID;
256
344
  static uint32_t s_next_image_ID;
257
345
 
258
346
  uint8_t* pixels[3];
 
347
  uint8_t  bpp_shift[3];  // 0 for 8 bit, 1 for 16 bit
259
348
 
260
349
  enum de265_chroma chroma_format;
261
350
 
291
380
  seq_parameter_set   sps;  // the SPS used for decoding this image
292
381
  pic_parameter_set   pps;  // the PPS used for decoding this image
293
382
  decoder_context*    decctx;
 
383
  class encoder_context*    encctx;
 
384
 
 
385
  int number_of_ctbs() const { return ctb_info.size(); }
294
386
 
295
387
private:
296
388
  MetaDataArray<CTB_info>    ctb_info;
297
389
  MetaDataArray<CB_ref_info> cb_info;
298
390
  MetaDataArray<PB_ref_info> pb_info;
299
391
  MetaDataArray<uint8_t>     intraPredMode;
 
392
  MetaDataArray<uint8_t>     intraPredModeC;
300
393
  MetaDataArray<uint8_t>     tu_info;
301
394
  MetaDataArray<uint8_t>     deblk_info;
302
395
 
307
400
  void*     user_data;
308
401
  void*     plane_user_data[3];  // this is logically attached to the pixel data pointers
309
402
  de265_image_allocation image_allocation_functions; // the functions used for memory allocation
 
403
  void (*encoder_image_release_func)(en265_encoder_context*,
 
404
                                     de265_image*,
 
405
                                     void* userdata);
310
406
 
311
407
  uint8_t integrity; /* Whether an error occured while the image was decoded.
312
408
                        When generated, this is initialized to INTEGRITY_CORRECT,
328
424
 
329
425
 
330
426
  void thread_start(int nThreads);
331
 
  void thread_run();
 
427
  void thread_run(const thread_task*);
332
428
  void thread_blocks();
333
429
  void thread_unblocks();
334
 
  void thread_finishes(); /* NOTE: you should not access any data in the thread_task after
335
 
                             calling this, as this function may unlock other threads that
336
 
                             will push this image to the output queue and free all decoder data. */
 
430
  /* NOTE: you should not access any data in the thread_task after
 
431
     calling this, as this function may unlock other threads that
 
432
     will push this image to the output queue and free all decoder data. */
 
433
  void thread_finishes(const thread_task*);
337
434
 
338
435
  void wait_for_progress(thread_task* task, int ctbx,int ctby, int progress);
339
436
  void wait_for_progress(thread_task* task, int ctbAddrRS, int progress);
384
481
    return get_pred_mode(x,y)==MODE_SKIP;
385
482
  }
386
483
 
387
 
  void set_pcm_flag(int x,int y, int log2BlkWidth)
 
484
  void set_pcm_flag(int x,int y, int log2BlkWidth, uint8_t value=1)
388
485
  {
389
 
    SET_CB_BLK(x,y,log2BlkWidth, pcm_flag, 1);
390
 
    ctb_info.get(x,y).has_pcm = true;
 
486
    SET_CB_BLK(x,y,log2BlkWidth, pcm_flag, value);
 
487
 
 
488
    // TODO: in the encoder, we somewhere have to clear this
 
489
    ctb_info.get(x,y).has_pcm_or_cu_transquant_bypass = true;
391
490
  }
392
491
 
393
492
  int  get_pcm_flag(int x,int y) const
395
494
    return cb_info.get(x,y).pcm_flag;
396
495
  }
397
496
 
398
 
  void set_cu_transquant_bypass(int x,int y, int log2BlkWidth)
 
497
  void set_cu_transquant_bypass(int x,int y, int log2BlkWidth, uint8_t value=1)
399
498
  {
400
 
    SET_CB_BLK(x,y,log2BlkWidth, cu_transquant_bypass, 1);
401
 
    ctb_info.get(x,y).has_cu_transquant_bypass = true;
 
499
    SET_CB_BLK(x,y,log2BlkWidth, cu_transquant_bypass, value);
 
500
 
 
501
    // TODO: in the encoder, we somewhere have to clear this
 
502
    ctb_info.get(x,y).has_pcm_or_cu_transquant_bypass = true;
402
503
  }
403
504
 
404
505
  int  get_cu_transquant_bypass(int x,int y) const
406
507
    return cb_info.get(x,y).cu_transquant_bypass;
407
508
  }
408
509
 
409
 
  void set_log2CbSize(int x0, int y0, int log2CbSize)
 
510
  void set_log2CbSize(int x0, int y0, int log2CbSize, bool fill)
410
511
  {
 
512
    // In theory, we could assume that remaining cb_info blocks are initialized to zero.
 
513
    // But in corrupted streams, slices may overlap and set contradicting log2CbSizes.
 
514
    // We also need this for encoding.
 
515
    if (fill) {
 
516
      SET_CB_BLK(x0,y0,log2CbSize, log2CbSize, 0);
 
517
    }
 
518
 
411
519
    cb_info.get(x0,y0).log2CbSize = log2CbSize;
412
 
 
413
 
    // assume that remaining cb_info blocks are initialized to zero
414
520
  }
415
521
 
416
522
  int  get_log2CbSize(int x0, int y0) const
461
567
    tu_info.get(x0,y0) |= (1<<trafoDepth);
462
568
  }
463
569
 
 
570
  void clear_split_transform_flags(int x0,int y0,int log2CbSize)
 
571
  {
 
572
    CLEAR_TB_BLK (x0,y0, log2CbSize);
 
573
  }
 
574
 
464
575
  int  get_split_transform_flag(int x0,int y0,int trafoDepth) const
465
576
  {
466
577
    return (tu_info.get(x0,y0) & (1<<trafoDepth));
500
611
  void set_IntraPredMode(int PUidx,int log2blkSize, enum IntraPredMode mode)
501
612
  {
502
613
    int pbSize = 1<<(log2blkSize - intraPredMode.log2unitSize);
503
 
    
 
614
 
504
615
    for (int y=0;y<pbSize;y++)
505
616
      for (int x=0;x<pbSize;x++)
506
617
        intraPredMode[PUidx + x + y*intraPredMode.width_in_units] = mode;
507
618
  }
508
619
 
 
620
  void set_IntraPredMode(int x0,int y0,int log2blkSize,
 
621
                         enum IntraPredMode mode)
 
622
  {
 
623
    int pbSize = 1<<(log2blkSize - intraPredMode.log2unitSize);
 
624
    int PUidx  = (x0>>sps.Log2MinPUSize) + (y0>>sps.Log2MinPUSize)*sps.PicWidthInMinPUs;
 
625
 
 
626
    for (int y=0;y<pbSize;y++)
 
627
      for (int x=0;x<pbSize;x++) {
 
628
        assert(x<sps.PicWidthInMinPUs);
 
629
        assert(y<sps.PicHeightInMinPUs);
 
630
 
 
631
        int idx = PUidx + x + y*intraPredMode.width_in_units;
 
632
        assert(idx<intraPredMode.data_size);
 
633
        intraPredMode[idx] = mode;
 
634
      }
 
635
  }
 
636
 
 
637
 
 
638
  enum IntraPredMode get_IntraPredModeC(int x,int y) const
 
639
  {
 
640
    return (enum IntraPredMode)(intraPredModeC.get(x,y) & 0x3f);
 
641
  }
 
642
 
 
643
  bool is_IntraPredModeC_Mode4(int x,int y) const
 
644
  {
 
645
    return intraPredModeC.get(x,y) & 0x80;
 
646
  }
 
647
 
 
648
  void set_IntraPredModeC(int x0,int y0,int log2blkSize, enum IntraPredMode mode,
 
649
                          bool is_mode4)
 
650
  {
 
651
    uint8_t combinedValue = mode;
 
652
    if (is_mode4) combinedValue |= 0x80;
 
653
 
 
654
    int pbSize = 1<<(log2blkSize - intraPredMode.log2unitSize);
 
655
    int PUidx  = (x0>>sps.Log2MinPUSize) + (y0>>sps.Log2MinPUSize)*sps.PicWidthInMinPUs;
 
656
 
 
657
    for (int y=0;y<pbSize;y++)
 
658
      for (int x=0;x<pbSize;x++) {
 
659
        assert(x<sps.PicWidthInMinPUs);
 
660
        assert(y<sps.PicHeightInMinPUs);
 
661
 
 
662
        int idx = PUidx + x + y*intraPredModeC.width_in_units;
 
663
        assert(idx<intraPredModeC.data_size);
 
664
        intraPredModeC[idx] = combinedValue;
 
665
      }
 
666
  }
 
667
 
 
668
 
 
669
  /*
 
670
  // NOTE: encoder only
 
671
  void set_ChromaIntraPredMode(int x,int y,int log2BlkWidth, enum IntraChromaPredMode mode)
 
672
  {
 
673
    SET_CB_BLK (x, y, log2BlkWidth, intra_chroma_pred_mode, mode);
 
674
  }
 
675
 
 
676
  // NOTE: encoder only
 
677
  enum IntraChromaPredMode get_ChromaIntraPredMode(int x,int y) const
 
678
  {
 
679
    return (enum IntraChromaPredMode)(cb_info.get(x,y).intra_chroma_pred_mode);
 
680
  }
 
681
  */
509
682
 
510
683
  // --- CTB metadata access ---
511
684
 
547
720
    return ctb_info[ctb].SliceHeaderIndex;
548
721
  }
549
722
 
 
723
  bool is_SliceHeader_available(int x,int y) const
 
724
  {
 
725
    int idx = ctb_info.get(x,y).SliceHeaderIndex;
 
726
    return idx >= 0 && idx < slices.size();
 
727
  }
 
728
 
550
729
  slice_segment_header* get_SliceHeader(int x, int y)
551
730
  {
552
 
    return slices[ get_SliceHeaderIndex(x,y) ];
 
731
    int idx = get_SliceHeaderIndex(x,y);
 
732
    if (idx >= slices.size()) { return NULL; }
 
733
    return slices[idx];
553
734
  }
554
735
 
555
736
  slice_segment_header* get_SliceHeaderCtb(int ctbX, int ctbY)
556
737
  {
557
 
    return slices[ get_SliceHeaderIndexCtb(ctbX,ctbY) ];
 
738
    int idx = get_SliceHeaderIndexCtb(ctbX,ctbY);
 
739
    if (idx >= slices.size()) { return NULL; }
 
740
    return slices[idx];
558
741
  }
559
742
 
560
743
  const slice_segment_header* get_SliceHeaderCtb(int ctbX, int ctbY) const
561
744
  {
562
 
    return slices[ get_SliceHeaderIndexCtb(ctbX,ctbY) ];
 
745
    int idx = get_SliceHeaderIndexCtb(ctbX,ctbY);
 
746
    if (idx >= slices.size()) { return NULL; }
 
747
    return slices[idx];
563
748
  }
564
 
  
 
749
 
565
750
  void set_sao_info(int ctbX,int ctbY,const sao_info* saoinfo)
566
751
  {
567
752
    sao_info* sao = &ctb_info[ctbX + ctbY*ctb_info.width_in_units].saoInfo;
568
 
    
 
753
 
569
754
    memcpy(sao,
570
755
           saoinfo,
571
756
           sizeof(sao_info));
572
757
  }
573
 
  
 
758
 
574
759
  const sao_info* get_sao_info(int ctbX,int ctbY) const
575
760
  {
576
761
    return &ctb_info[ctbX + ctbY*ctb_info.width_in_units].saoInfo;
589
774
  }
590
775
 
591
776
 
592
 
  bool get_CTB_has_pcm(int ctbX,int ctbY) const
593
 
  {
594
 
    int idx = ctbX + ctbY*ctb_info.width_in_units;
595
 
    return ctb_info[idx].has_pcm;
596
 
  }
597
 
 
598
 
  bool get_CTB_has_cu_transquant_bypass(int ctbX,int ctbY) const
599
 
  {
600
 
    int idx = ctbX + ctbY*ctb_info.width_in_units;
601
 
    return ctb_info[idx].has_cu_transquant_bypass;
 
777
  bool get_CTB_has_pcm_or_cu_transquant_bypass(int ctbX,int ctbY) const
 
778
  {
 
779
    int idx = ctbX + ctbY*ctb_info.width_in_units;
 
780
    return ctb_info[idx].has_pcm_or_cu_transquant_bypass;
602
781
  }
603
782
 
604
783
 
612
791
  {
613
792
    const int xd = x0/4;
614
793
    const int yd = y0/4;
615
 
    
 
794
 
616
795
    if (xd<deblk_info.width_in_units &&
617
796
        yd<deblk_info.height_in_units) {
618
797
      deblk_info[xd + yd*deblk_info.width_in_units] |= flags;
642
821
 
643
822
  // --- PB metadata access ---
644
823
 
645
 
  const PredVectorInfo* get_mv_info(int x,int y) const
 
824
  const MotionVectorSpec* get_mv_info(int x,int y) const
646
825
  {
647
 
    return &pb_info.get(x,y).mvi;
 
826
    return &pb_info.get(x,y).mv;
648
827
  }
649
828
 
650
 
  void set_mv_info(int x,int y, int nPbW,int nPbH, const PredVectorInfo* mv);
651
 
 
652
 
// --- value logging ---
653
 
 
 
829
  void set_mv_info(int x,int y, int nPbW,int nPbH, const MotionVectorSpec& mv);
 
830
 
 
831
  // --- value logging ---
 
832
 
 
833
  void printBlk(int x0,int y0, int cIdx, int log2BlkSize);
654
834
};
655
835
 
656
836