OpenCores
URL https://opencores.org/ocsvn/bluespec-h264/bluespec-h264/trunk

Subversion Repositories bluespec-h264

[/] [bluespec-h264/] [trunk/] [test/] [decoder/] [ldecod/] [src/] [mb_access.c] - Blame information for rev 100

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jamey.hick
 
2
/*!
3
 *************************************************************************************
4
 * \file mb_access.c
5
 *
6
 * \brief
7
 *    Functions for macroblock neighborhoods
8
 *
9
 *  \author
10
 *      Main contributors (see contributors.h for copyright, address and affiliation details)
11
 *      - Karsten Sühring          <suehring@hhi.de>
12
 *************************************************************************************
13
 */
14
#include <assert.h>
15
 
16
#include "global.h"
17
#include "mbuffer.h"
18
#include "mb_access.h"
19
 
20
extern StorablePicture *dec_picture;
21
 
22
/*!
23
 ************************************************************************
24
 * \brief
25
 *    returns 1 if the macroblock at the given address is available
26
 ************************************************************************
27
 */
28
int mb_is_available(int mbAddr, int currMbAddr)
29
{
30
  if ((mbAddr < 0) || (mbAddr > ((int)dec_picture->PicSizeInMbs - 1)))
31
    return 0;
32
 
33
  // the following line checks both: slice number and if the mb has been decoded
34
  if (!img->DeblockCall)
35
  {
36
    if (img->mb_data[mbAddr].slice_nr != img->mb_data[currMbAddr].slice_nr)
37
      return 0;
38
  }
39
 
40
  return 1;
41
}
42
 
43
 
44
/*!
45
 ************************************************************************
46
 * \brief
47
 *    Checks the availability of neighboring macroblocks of
48
 *    the current macroblock for prediction and context determination;
49
 ************************************************************************
50
 */
51
void CheckAvailabilityOfNeighbors(void)
52
{
53
  const int mb_nr = img->current_mb_nr;
54
  Macroblock *currMB = &img->mb_data[mb_nr];
55
 
56
  // mark all neighbors as unavailable
57
  currMB->mb_available_up   = NULL;
58
  currMB->mb_available_left = NULL;
59
 
60
  if (dec_picture->MbaffFrameFlag)
61
  {
62
    int cur_mb_pair = mb_nr >> 1;
63
    currMB->mbAddrA = 2 * (cur_mb_pair - 1);
64
    currMB->mbAddrB = 2 * (cur_mb_pair - dec_picture->PicWidthInMbs);
65
    currMB->mbAddrC = 2 * (cur_mb_pair - dec_picture->PicWidthInMbs + 1);
66
    currMB->mbAddrD = 2 * (cur_mb_pair - dec_picture->PicWidthInMbs - 1);
67
 
68
    currMB->mbAvailA = mb_is_available(currMB->mbAddrA, mb_nr) && ((PicPos[ cur_mb_pair     ][0])!=0);
69
    currMB->mbAvailB = mb_is_available(currMB->mbAddrB, mb_nr);
70
    currMB->mbAvailC = mb_is_available(currMB->mbAddrC, mb_nr) && ((PicPos[ cur_mb_pair + 1 ][0])!=0);
71
    currMB->mbAvailD = mb_is_available(currMB->mbAddrD, mb_nr) && ((PicPos[ cur_mb_pair     ][0])!=0);
72
  }
73
  else
74
  {
75
    currMB->mbAddrA = mb_nr - 1;
76
    currMB->mbAddrB = mb_nr - dec_picture->PicWidthInMbs;
77
    currMB->mbAddrC = mb_nr - dec_picture->PicWidthInMbs + 1;
78
    currMB->mbAddrD = mb_nr - dec_picture->PicWidthInMbs - 1;
79
 
80
    currMB->mbAvailA = mb_is_available(currMB->mbAddrA, mb_nr) && ((PicPos[ mb_nr    ][0])!=0);
81
    currMB->mbAvailB = mb_is_available(currMB->mbAddrB, mb_nr);
82
    currMB->mbAvailC = mb_is_available(currMB->mbAddrC, mb_nr) && ((PicPos[ mb_nr + 1][0])!=0);
83
    currMB->mbAvailD = mb_is_available(currMB->mbAddrD, mb_nr) && ((PicPos[ mb_nr    ][0])!=0);
84
  }
85
}
86
 
87
 
88
/*!
89
 ************************************************************************
90
 * \brief
91
 *    returns the x and y macroblock coordinates for a given MbAddress
92
 ************************************************************************
93
 */
94
void get_mb_block_pos_normal (int mb_addr, int *x, int*y)
95
{
96
  *x = PicPos[ mb_addr ][0];
97
  *y = PicPos[ mb_addr ][1];
98
}
99
 
100
/*!
101
 ************************************************************************
102
 * \brief
103
 *    returns the x and y macroblock coordinates for a given MbAddress
104
 *    for mbaff type slices
105
 ************************************************************************
106
 */
107
void get_mb_block_pos_mbaff (int mb_addr, int *x, int*y)
108
{
109
  *x =  PicPos[mb_addr>>1][0];
110
  *y = (PicPos[mb_addr>>1][1] << 1) + (mb_addr & 0x01);
111
}
112
 
113
/*!
114
 ************************************************************************
115
 * \brief
116
 *    returns the x and y sample coordinates for a given MbAddress
117
 ************************************************************************
118
 */
119
void get_mb_pos (int mb_addr, int *x, int*y, int is_chroma)
120
{
121
  get_mb_block_pos(mb_addr, x, y);
122
 
123
  (*x) *= img->mb_size[is_chroma][0];
124
  (*y) *= img->mb_size[is_chroma][1];
125
}
126
 
127
 
128
/*!
129
 ************************************************************************
130
 * \brief
131
 *    get neighbouring positions for non-aff coding
132
 * \param curr_mb_nr
133
 *   current macroblock number (decoding order)
134
 * \param xN
135
 *    input x position
136
 * \param yN
137
 *    input y position
138
 * \param luma
139
 *    1 if luma coding, 0 for chroma
140
 * \param pix
141
 *    returns position informations
142
 ************************************************************************
143
 */
144
void getNonAffNeighbour(unsigned int curr_mb_nr, int xN, int yN, int is_chroma, PixelPos *pix)
145
{
146
  Macroblock *currMb = &img->mb_data[curr_mb_nr];
147
  int maxW = img->mb_size[is_chroma][0], maxH = img->mb_size[is_chroma][1];
148
/*
149
  if (!is_chroma)
150
  {
151
    maxW = 16;
152
    maxH = 16;
153
  }
154
  else
155
  {
156
    assert(dec_picture->chroma_format_idc != 0);
157
    maxW = img->mb_cr_size_x;
158
    maxH = img->mb_cr_size_y;
159
  }
160
*/
161
 
162
  if ((xN<0))
163
  {
164
    if (yN<0)
165
    {
166
      pix->mb_addr   = currMb->mbAddrD;
167
      pix->available = currMb->mbAvailD;
168
    }
169
    else if (yN<maxH)
170
    {
171
      pix->mb_addr  = currMb->mbAddrA;
172
      pix->available = currMb->mbAvailA;
173
    }
174
    else
175
      pix->available = FALSE;
176
  }
177
  else if (xN<maxW)
178
  {
179
    if (yN<0)
180
    {
181
      pix->mb_addr  = currMb->mbAddrB;
182
      pix->available = currMb->mbAvailB;
183
    }
184
    else if (yN<maxH)
185
    {
186
      pix->mb_addr  = curr_mb_nr;
187
      pix->available = TRUE;
188
    }
189
    else
190
    {
191
      pix->available = FALSE;
192
    }
193
  }
194
  else if ((xN>=maxW)&&(yN<0))
195
  {
196
    pix->mb_addr  = currMb->mbAddrC;
197
    pix->available = currMb->mbAvailC;
198
  }
199
  else
200
  {
201
    pix->available = FALSE;
202
  }
203
 
204
  if (pix->available || img->DeblockCall)
205
  {
206
    int *CurPos = PicPos[ pix->mb_addr ];
207
 
208
    pix->x = xN & (maxW - 1);
209
    pix->y = yN & (maxH - 1);
210
    pix->pos_x = CurPos[0] * maxW + pix->x;
211
    pix->pos_y = CurPos[1] * maxH + pix->y;
212
  }
213
}
214
 
215
/*!
216
 ************************************************************************
217
 * \brief
218
 *    get neighbouring positions for aff coding
219
 * \param curr_mb_nr
220
 *   current macroblock number (decoding order)
221
 * \param xN
222
 *    input x position
223
 * \param yN
224
 *    input y position
225
 * \param luma
226
 *    1 if luma coding, 0 for chroma
227
 * \param pix
228
 *    returns position informations
229
 ************************************************************************
230
 */
231
void getAffNeighbour(unsigned int curr_mb_nr, int xN, int yN, int is_chroma, PixelPos *pix)
232
{
233
  Macroblock *currMb = &img->mb_data[curr_mb_nr];
234
  int maxW, maxH;
235
  int yM = -1;
236
 
237
/*
238
  if (!is_chroma)
239
  {
240
    maxW = 16;
241
    maxH = 16;
242
  }
243
  else
244
  {
245
    assert(dec_picture->chroma_format_idc != 0);
246
    maxW = img->mb_cr_size_x;
247
    maxH = img->mb_cr_size_y;
248
  }
249
*/
250
  maxW = img->mb_size[is_chroma][0];
251
  maxH = img->mb_size[is_chroma][1];
252
 
253
  // initialize to "not available"
254
  pix->available = FALSE;
255
 
256
  if(yN > (maxH - 1))
257
  {
258
    return;
259
  }
260
  if (xN > (maxW - 1) && yN >= 0 && yN < maxH)
261
  {
262
    return;
263
  }
264
 
265
  if (xN < 0)
266
  {
267
    if (yN < 0)
268
    {
269
      if(!currMb->mb_field)
270
      {
271
        // frame
272
        if ((curr_mb_nr & 0x01) == 0)
273
        {
274
          // top
275
          pix->mb_addr   = currMb->mbAddrD  + 1;
276
          pix->available = currMb->mbAvailD;
277
          yM = yN;
278
        }
279
        else
280
        {
281
          // bottom
282
          pix->mb_addr   = currMb->mbAddrA;
283
          pix->available = currMb->mbAvailA;
284
          if (currMb->mbAvailA)
285
          {
286
            if(!img->mb_data[currMb->mbAddrA].mb_field)
287
            {
288
               yM = yN;
289
            }
290
            else
291
            {
292
              (pix->mb_addr)++;
293
               yM = (yN + maxH) >> 1;
294
            }
295
          }
296
        }
297
      }
298
      else
299
      {
300
        // field
301
        if ((curr_mb_nr & 0x01) == 0)
302
        {
303
          // top
304
          pix->mb_addr   = currMb->mbAddrD;
305
          pix->available = currMb->mbAvailD;
306
          if (currMb->mbAvailD)
307
          {
308
            if(!img->mb_data[currMb->mbAddrD].mb_field)
309
            {
310
              (pix->mb_addr)++;
311
               yM = 2 * yN;
312
            }
313
            else
314
            {
315
               yM = yN;
316
            }
317
          }
318
        }
319
        else
320
        {
321
          // bottom
322
          pix->mb_addr   = currMb->mbAddrD+1;
323
          pix->available = currMb->mbAvailD;
324
          yM = yN;
325
        }
326
      }
327
    }
328
    else
329
    { // xN < 0 && yN >= 0
330
      if (yN >= 0 && yN <maxH)
331
      {
332
        if (!currMb->mb_field)
333
        {
334
          // frame
335
          if ((curr_mb_nr & 0x01) == 0)
336
          {
337
            // top
338
            pix->mb_addr   = currMb->mbAddrA;
339
            pix->available = currMb->mbAvailA;
340
            if (currMb->mbAvailA)
341
            {
342
              if(!img->mb_data[currMb->mbAddrA].mb_field)
343
              {
344
                 yM = yN;
345
              }
346
              else
347
              {
348
                if ((yN & 0x01) == 0)
349
                {
350
                   yM = yN>> 1;
351
                }
352
                else
353
                {
354
                  (pix->mb_addr)++;
355
                   yM = yN>> 1;
356
                }
357
              }
358
            }
359
          }
360
          else
361
          {
362
            // bottom
363
            pix->mb_addr   = currMb->mbAddrA;
364
            pix->available = currMb->mbAvailA;
365
            if (currMb->mbAvailA)
366
            {
367
              if(!img->mb_data[currMb->mbAddrA].mb_field)
368
              {
369
                (pix->mb_addr)++;
370
                 yM = yN;
371
              }
372
              else
373
              {
374
                if ((yN & 0x01) == 0)
375
                {
376
                   yM = (yN + maxH) >> 1;
377
                }
378
                else
379
                {
380
                  (pix->mb_addr)++;
381
                   yM = (yN + maxH) >> 1;
382
                }
383
              }
384
            }
385
          }
386
        }
387
        else
388
        {
389
          // field
390
          if ((curr_mb_nr & 0x01) == 0)
391
          {
392
            // top
393
            pix->mb_addr  = currMb->mbAddrA;
394
            pix->available = currMb->mbAvailA;
395
            if (currMb->mbAvailA)
396
            {
397
              if(!img->mb_data[currMb->mbAddrA].mb_field)
398
              {
399
                if (yN < (maxH >> 1))
400
                {
401
                   yM = yN << 1;
402
                }
403
                else
404
                {
405
                  (pix->mb_addr)++;
406
                   yM = (yN << 1 ) - maxH;
407
                }
408
              }
409
              else
410
              {
411
                 yM = yN;
412
              }
413
            }
414
          }
415
          else
416
          {
417
            // bottom
418
            pix->mb_addr  = currMb->mbAddrA;
419
            pix->available = currMb->mbAvailA;
420
            if (currMb->mbAvailA)
421
            {
422
              if(!img->mb_data[currMb->mbAddrA].mb_field)
423
              {
424
                if (yN < (maxH >> 1))
425
                {
426
                  yM = (yN << 1) + 1;
427
                }
428
                else
429
                {
430
                  (pix->mb_addr)++;
431
                   yM = (yN << 1 ) + 1 - maxH;
432
                }
433
              }
434
              else
435
              {
436
                (pix->mb_addr)++;
437
                 yM = yN;
438
              }
439
            }
440
          }
441
        }
442
      }
443
    }
444
  }
445
  else
446
  { // xN >= 0
447
    if (xN >= 0 && xN < maxW)
448
    {
449
      if (yN<0)
450
      {
451
        if (!currMb->mb_field)
452
        {
453
          //frame
454
          if ((curr_mb_nr & 0x01) == 0)
455
          {
456
            //top
457
            pix->mb_addr  = currMb->mbAddrB;
458
            // for the deblocker if the current MB is a frame and the one above is a field
459
            // then the neighbor is the top MB of the pair
460
            if (currMb->mbAvailB)
461
            {
462
              if (!(img->DeblockCall == 1 && (img->mb_data[currMb->mbAddrB]).mb_field))
463
                pix->mb_addr  += 1;
464
            }
465
 
466
            pix->available = currMb->mbAvailB;
467
            yM = yN;
468
          }
469
          else
470
          {
471
            // bottom
472
            pix->mb_addr   = curr_mb_nr - 1;
473
            pix->available = TRUE;
474
            yM = yN;
475
          }
476
        }
477
        else
478
        {
479
          // field
480
          if ((curr_mb_nr & 0x01) == 0)
481
          {
482
            // top
483
            pix->mb_addr   = currMb->mbAddrB;
484
            pix->available = currMb->mbAvailB;
485
            if (currMb->mbAvailB)
486
            {
487
              if(!img->mb_data[currMb->mbAddrB].mb_field)
488
              {
489
                (pix->mb_addr)++;
490
                 yM = 2* yN;
491
              }
492
              else
493
              {
494
                 yM = yN;
495
              }
496
            }
497
          }
498
          else
499
          {
500
            // bottom
501
            pix->mb_addr   = currMb->mbAddrB + 1;
502
            pix->available = currMb->mbAvailB;
503
            yM = yN;
504
          }
505
        }
506
      }
507
      else
508
      {
509
        // yN >=0
510
        // for the deblocker if this is the extra edge then do this special stuff
511
        if (yN == 0 && img->DeblockCall == 2)
512
        {
513
          pix->mb_addr  = currMb->mbAddrB + 1;
514
          pix->available = TRUE;
515
          yM = yN - 1;
516
        }
517
 
518
        else if ((yN >= 0) && (yN <maxH))
519
        {
520
          pix->mb_addr   = curr_mb_nr;
521
          pix->available = TRUE;
522
          yM = yN;
523
        }
524
      }
525
    }
526
    else
527
    { // xN >= maxW
528
      if(yN < 0)
529
      {
530
        if (!currMb->mb_field)
531
        {
532
          // frame
533
          if ((curr_mb_nr & 0x01) == 0)
534
          {
535
            // top
536
            pix->mb_addr  = currMb->mbAddrC + 1;
537
            pix->available = currMb->mbAvailC;
538
            yM = yN;
539
          }
540
          else
541
          {
542
            // bottom
543
            pix->available = FALSE;
544
          }
545
        }
546
        else
547
        {
548
          // field
549
          if ((curr_mb_nr & 0x01) == 0)
550
          {
551
            // top
552
            pix->mb_addr   = currMb->mbAddrC;
553
            pix->available = currMb->mbAvailC;
554
            if (currMb->mbAvailC)
555
            {
556
              if(!img->mb_data[currMb->mbAddrC].mb_field)
557
              {
558
                (pix->mb_addr)++;
559
                 yM = 2* yN;
560
              }
561
              else
562
              {
563
                yM = yN;
564
              }
565
            }
566
          }
567
          else
568
          {
569
            // bottom
570
            pix->mb_addr   = currMb->mbAddrC + 1;
571
            pix->available = currMb->mbAvailC;
572
            yM = yN;
573
          }
574
        }
575
      }
576
    }
577
  }
578
  if (pix->available || img->DeblockCall)
579
  {
580
    pix->x = xN & (maxW - 1);
581
    pix->y = yM & (maxH - 1);
582
    get_mb_pos(pix->mb_addr, &(pix->pos_x), &(pix->pos_y), is_chroma);
583
    pix->pos_x += pix->x;
584
    pix->pos_y += pix->y;
585
  }
586
}
587
 
588
 
589
/*!
590
 ************************************************************************
591
 * \brief
592
 *    get neighbouring positions. MB AFF is automatically used from img structure
593
 * \param curr_mb_nr
594
 *   current macroblock number (decoding order)
595
 * \param xN
596
 *    input x position
597
 * \param yN
598
 *    input y position
599
 * \param luma
600
 *    1 if luma coding, 0 for chroma
601
 * \param pix
602
 *    returns position informations
603
 ************************************************************************
604
 */
605
/*
606
void getNeighbour(int curr_mb_nr, int xN, int yN, int is_chroma, PixelPos *pix)
607
{
608
  if (curr_mb_nr<0)
609
    error ("getNeighbour: invalid macroblock number", 100);
610
 
611
  if (dec_picture->MbaffFrameFlag)
612
    getAffNeighbour(curr_mb_nr, xN, yN, is_chroma, pix);
613
  else
614
    getNonAffNeighbour(curr_mb_nr, xN, yN, is_chroma, pix);
615
}
616
*/
617
 
618
/*!
619
 ************************************************************************
620
 * \brief
621
 *    get neighbouring  get neighbouring 4x4 luma block
622
 * \param curr_mb_nr
623
 *   current macroblock number (decoding order)
624
 * \param block_x
625
 *    input x block position
626
 * \param block_y
627
 *    input y block position
628
 * \param rel_x
629
 *    relative x position of neighbor
630
 * \param rel_y
631
 *    relative y position of neighbor
632
 * \param pix
633
 *    returns position informations
634
 ************************************************************************
635
 */
636
void getLuma4x4Neighbour (int curr_mb_nr, int block_x, int block_y, PixelPos *pix)
637
{
638
  getNeighbour(curr_mb_nr, block_x, block_y, IS_LUMA, pix);
639
 
640
  if (pix->available)
641
  {
642
    pix->x >>= 2;
643
    pix->y >>= 2;
644
    pix->pos_x >>= 2;
645
    pix->pos_y >>= 2;
646
  }
647
}
648
 
649
 
650
/*!
651
 ************************************************************************
652
 * \brief
653
 *    get neighbouring 4x4 chroma block
654
 * \param curr_mb_nr
655
 *   current macroblock number (decoding order)
656
 * \param block_x
657
 *    input x block position
658
 * \param block_y
659
 *    input y block position
660
 * \param rel_x
661
 *    relative x position of neighbor
662
 * \param rel_y
663
 *    relative y position of neighbor
664
 * \param pix
665
 *    returns position informations
666
 ************************************************************************
667
 */
668
void getChroma4x4Neighbour (int curr_mb_nr, int block_x, int block_y, PixelPos *pix)
669
{
670
  getNeighbour(curr_mb_nr, block_x, block_y, IS_CHROMA, pix);
671
 
672
  if (pix->available)
673
  {
674
    pix->x >>= 2;
675
    pix->y >>= 2;
676
    pix->pos_x >>= 2;
677
    pix->pos_y >>= 2;
678
  }
679
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.