• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 #include "avclib_common.h"
19 #include "oscl_mem.h"
20 
InitNeighborAvailability(AVCCommonObj * video,int mbNum)21 OSCL_EXPORT_REF void InitNeighborAvailability(AVCCommonObj *video, int mbNum)
22 {
23     int PicWidthInMbs = video->PicWidthInMbs;
24 
25     // do frame-only and postpone intraAvail calculattion
26     video->mbAddrA = mbNum - 1;
27     video->mbAddrB = mbNum - PicWidthInMbs;
28     video->mbAddrC = mbNum - PicWidthInMbs + 1;
29     video->mbAddrD = mbNum - PicWidthInMbs - 1;
30 
31     video->mbAvailA = video->mbAvailB = video->mbAvailC = video->mbAvailD = 0;
32     if (video->mb_x)
33     {
34         video->mbAvailA = (video->mblock[video->mbAddrA].slice_id == video->currMB->slice_id);
35         if (video->mb_y)
36         {
37             video->mbAvailD = (video->mblock[video->mbAddrD].slice_id == video->currMB->slice_id);
38         }
39     }
40 
41     if (video->mb_y)
42     {
43         video->mbAvailB = (video->mblock[video->mbAddrB].slice_id == video->currMB->slice_id);
44         if (video->mb_x < (PicWidthInMbs - 1))
45         {
46             video->mbAvailC = (video->mblock[video->mbAddrC].slice_id == video->currMB->slice_id);
47         }
48     }
49     return ;
50 }
51 
mb_is_available(AVCMacroblock * mblock,uint PicSizeInMbs,int mbAddr,int currMbAddr)52 bool mb_is_available(AVCMacroblock *mblock, uint PicSizeInMbs, int mbAddr, int currMbAddr)
53 {
54     if (mbAddr < 0 || mbAddr >= (int)PicSizeInMbs)
55     {
56         return FALSE;
57     }
58 
59     if (mblock[mbAddr].slice_id != mblock[currMbAddr].slice_id)
60     {
61         return FALSE;
62     }
63 
64     return TRUE;
65 }
66 
predict_nnz(AVCCommonObj * video,int i,int j)67 OSCL_EXPORT_REF int predict_nnz(AVCCommonObj *video, int i, int j)
68 {
69     int pred_nnz = 0;
70     int cnt      = 1;
71     AVCMacroblock *tempMB;
72 
73     /* left block */
74     /*getLuma4x4Neighbour(video, mb_nr, i, j, -1, 0, &pix);
75     leftMB = video->mblock + pix.mb_addr; */
76     /* replace the above with below (won't work for field decoding),  1/19/04 */
77 
78     if (i)
79     {
80         pred_nnz = video->currMB->nz_coeff[(j<<2)+i-1];
81     }
82     else
83     {
84         if (video->mbAvailA)
85         {
86             tempMB = video->mblock + video->mbAddrA;
87             pred_nnz = tempMB->nz_coeff[(j<<2)+3];
88         }
89         else
90         {
91             cnt = 0;
92         }
93     }
94 
95 
96     /* top block */
97     /*getLuma4x4Neighbour(video, mb_nr, i, j, 0, -1, &pix);
98     topMB = video->mblock + pix.mb_addr;*/
99     /* replace the above with below (won't work for field decoding),  1/19/04 */
100 
101     if (j)
102     {
103         pred_nnz += video->currMB->nz_coeff[((j-1)<<2)+i];
104         cnt++;
105     }
106     else
107     {
108         if (video->mbAvailB)
109         {
110             tempMB = video->mblock + video->mbAddrB;
111             pred_nnz += tempMB->nz_coeff[12+i];
112             cnt++;
113         }
114     }
115 
116 
117     if (cnt == 2)
118     {
119         pred_nnz = (pred_nnz + 1) >> 1;
120     }
121 
122     return pred_nnz;
123 
124 }
125 
126 
predict_nnz_chroma(AVCCommonObj * video,int i,int j)127 OSCL_EXPORT_REF int predict_nnz_chroma(AVCCommonObj *video, int i, int j)
128 {
129     int pred_nnz = 0;
130     int cnt      = 1;
131     AVCMacroblock *tempMB;
132 
133     /* left block */
134     /*getChroma4x4Neighbour(video, mb_nr, i%2, j-4, -1, 0, &pix);
135     leftMB = video->mblock + pix.mb_addr;*/
136     /* replace the above with below (won't work for field decoding),  1/19/04 */
137     if (i&1)
138     {
139         pred_nnz = video->currMB->nz_coeff[(j<<2)+i-1];
140 
141     }
142     else
143     {
144         if (video->mbAvailA)
145         {
146             tempMB = video->mblock + video->mbAddrA;
147             pred_nnz = tempMB->nz_coeff[(j<<2)+i+1];
148         }
149         else
150         {
151             cnt = 0;
152         }
153     }
154 
155 
156     /* top block */
157     /*getChroma4x4Neighbour(video, mb_nr, i%2, j-4, 0, -1, &pix);
158     topMB = video->mblock + pix.mb_addr;*/
159     /* replace the above with below (won't work for field decoding),  1/19/04 */
160 
161     if (j&1)
162     {
163         pred_nnz += video->currMB->nz_coeff[((j-1)<<2)+i];
164         cnt++;
165     }
166     else
167     {
168         if (video->mbAvailB)
169         {
170             tempMB = video->mblock + video->mbAddrB;
171             pred_nnz += tempMB->nz_coeff[20+i];
172             cnt++;
173         }
174 
175     }
176 
177     if (cnt == 2)
178     {
179         pred_nnz = (pred_nnz + 1) >> 1;
180     }
181 
182     return pred_nnz;
183 }
184 
GetMotionVectorPredictor(AVCCommonObj * video,int encFlag)185 OSCL_EXPORT_REF void GetMotionVectorPredictor(AVCCommonObj *video, int encFlag)
186 {
187     AVCMacroblock *currMB = video->currMB;
188     AVCMacroblock *MB_A, *MB_B, *MB_C, *MB_D;
189     int block_x, block_y, block_x_1, block_y_1, new_block_x;
190     int mbPartIdx, subMbPartIdx, offset_indx;
191     int16 *mv, pmv_x, pmv_y;
192     int nmSubMbHeight, nmSubMbWidth, mbPartIdx_X, mbPartIdx_Y;
193     int avail_a, avail_b, avail_c;
194     const static uint32 C = 0x5750;
195     int i, j, offset_MbPart_indx, refIdxLXA, refIdxLXB, refIdxLXC = 0, curr_ref_idx;
196     int pmv_A_x, pmv_B_x, pmv_C_x = 0, pmv_A_y, pmv_B_y, pmv_C_y = 0;
197 
198     /* we have to take care of Intra/skip blocks somewhere, i.e. set MV to  0 and set ref to -1! */
199     /* we have to populate refIdx as well */
200 
201 
202     MB_A = &video->mblock[video->mbAddrA];
203     MB_B = &video->mblock[video->mbAddrB];
204 
205 
206     if (currMB->mbMode == AVC_SKIP /* && !encFlag */) /* only for decoder */
207     {
208         currMB->ref_idx_L0[0] = currMB->ref_idx_L0[1] = currMB->ref_idx_L0[2] = currMB->ref_idx_L0[3] = 0;
209         if (video->mbAvailA && video->mbAvailB)
210         {
211             if ((MB_A->ref_idx_L0[1] == 0 && MB_A->mvL0[3] == 0) ||
212                     (MB_B->ref_idx_L0[2] == 0 && MB_B->mvL0[12] == 0))
213             {
214                 oscl_memset(currMB->mvL0, 0, sizeof(int32)*16);
215                 return;
216             }
217         }
218         else
219         {
220             oscl_memset(currMB->mvL0, 0, sizeof(int32)*16);
221             return;
222         }
223         video->mvd_l0[0][0][0] = 0;
224         video->mvd_l0[0][0][1] = 0;
225     }
226 
227     MB_C = &video->mblock[video->mbAddrC];
228     MB_D = &video->mblock[video->mbAddrD];
229 
230     offset_MbPart_indx = 0;
231     for (mbPartIdx = 0; mbPartIdx < currMB->NumMbPart; mbPartIdx++)
232     {
233         offset_indx = 0;
234         nmSubMbHeight = currMB->SubMbPartHeight[mbPartIdx] >> 2;
235         nmSubMbWidth = currMB->SubMbPartWidth[mbPartIdx] >> 2;
236         mbPartIdx_X = ((mbPartIdx + offset_MbPart_indx) & 1) << 1;
237         mbPartIdx_Y = (mbPartIdx + offset_MbPart_indx) & 2;
238 
239         for (subMbPartIdx = 0; subMbPartIdx < currMB->NumSubMbPart[mbPartIdx]; subMbPartIdx++)
240         {
241             block_x = mbPartIdx_X + ((subMbPartIdx + offset_indx) & 1);
242             block_y = mbPartIdx_Y + (((subMbPartIdx + offset_indx) >> 1) & 1);
243 
244             block_x_1 = block_x - 1;
245             block_y_1 = block_y - 1;
246             refIdxLXA = refIdxLXB = refIdxLXC = -1;
247             pmv_A_x = pmv_A_y = pmv_B_x = pmv_B_y = pmv_C_x = pmv_C_y = 0;
248 
249             if (block_x)
250             {
251                 avail_a = 1;
252                 refIdxLXA = currMB->ref_idx_L0[(block_y & 2) + (block_x_1 >> 1)];
253                 mv = (int16*)(currMB->mvL0 + (block_y << 2) + block_x_1);
254                 pmv_A_x = *mv++;
255                 pmv_A_y = *mv;
256             }
257             else
258             {
259                 avail_a = video->mbAvailA;
260                 if (avail_a)
261                 {
262                     refIdxLXA = MB_A->ref_idx_L0[(block_y & 2) + 1];
263                     mv = (int16*)(MB_A->mvL0 + (block_y << 2) + 3);
264                     pmv_A_x = *mv++;
265                     pmv_A_y = *mv;
266                 }
267             }
268 
269             if (block_y)
270             {
271                 avail_b = 1;
272                 refIdxLXB = currMB->ref_idx_L0[(block_y_1 & 2) + (block_x >> 1)];
273                 mv = (int16*)(currMB->mvL0 + (block_y_1 << 2) + block_x);
274                 pmv_B_x = *mv++;
275                 pmv_B_y = *mv;
276             }
277 
278             else
279             {
280                 avail_b = video->mbAvailB;
281                 if (avail_b)
282                 {
283                     refIdxLXB = MB_B->ref_idx_L0[2 + (block_x >> 1)];
284                     mv = (int16*)(MB_B->mvL0 + 12 + block_x);
285                     pmv_B_x = *mv++;
286                     pmv_B_y = *mv;
287                 }
288             }
289 
290             new_block_x = block_x + (currMB->SubMbPartWidth[mbPartIdx] >> 2) - 1;
291             avail_c = (C >> ((block_y << 2) + new_block_x)) & 0x1;
292 
293             if (avail_c)
294             {
295                 /* it guaranteed that block_y > 0 && new_block_x<3 ) */
296                 refIdxLXC = currMB->ref_idx_L0[(block_y_1 & 2) + ((new_block_x+1) >> 1)];
297                 mv = (int16*)(currMB->mvL0 + (block_y_1 << 2) + (new_block_x + 1));
298                 pmv_C_x = *mv++;
299                 pmv_C_y = *mv;
300             }
301             else
302             {
303                 if (block_y == 0 && new_block_x < 3)
304                 {
305                     avail_c = video->mbAvailB;
306                     if (avail_c)
307                     {
308                         refIdxLXC = MB_B->ref_idx_L0[2 + ((new_block_x+1)>>1)];
309                         mv = (int16*)(MB_B->mvL0 + 12 + (new_block_x + 1));
310                         pmv_C_x = *mv++;
311                         pmv_C_y = *mv;
312                     }
313                 }
314                 else if (block_y == 0 && new_block_x == 3)
315                 {
316                     avail_c = video->mbAvailC;
317                     if (avail_c)
318                     {
319                         refIdxLXC = MB_C->ref_idx_L0[2];
320                         mv = (int16*)(MB_C->mvL0 + 12);
321                         pmv_C_x = *mv++;
322                         pmv_C_y = *mv;
323                     }
324                 }
325 
326                 if (avail_c == 0)
327                 {   /* check D */
328                     if (block_x && block_y)
329                     {
330                         avail_c = 1;
331                         refIdxLXC =  currMB->ref_idx_L0[(block_y_1 & 2) + (block_x_1 >> 1)];
332                         mv = (int16*)(currMB->mvL0 + (block_y_1 << 2) + block_x_1);
333                         pmv_C_x = *mv++;
334                         pmv_C_y = *mv;
335                     }
336                     else if (block_y)
337                     {
338                         avail_c = video->mbAvailA;
339                         if (avail_c)
340                         {
341                             refIdxLXC =  MB_A->ref_idx_L0[(block_y_1 & 2) + 1];
342                             mv = (int16*)(MB_A->mvL0 + (block_y_1 << 2) + 3);
343                             pmv_C_x = *mv++;
344                             pmv_C_y = *mv;
345                         }
346                     }
347                     else if (block_x)
348                     {
349                         avail_c = video->mbAvailB;
350                         if (avail_c)
351                         {
352                             refIdxLXC = MB_B->ref_idx_L0[2 + (block_x_1 >> 1)];
353                             mv = (int16*)(MB_B->mvL0 + 12 + block_x_1);
354                             pmv_C_x = *mv++;
355                             pmv_C_y = *mv;
356                         }
357                     }
358                     else
359                     {
360                         avail_c = video->mbAvailD;
361                         if (avail_c)
362                         {
363                             refIdxLXC = MB_D->ref_idx_L0[3];
364                             mv = (int16*)(MB_D->mvL0 + 15);
365                             pmv_C_x = *mv++;
366                             pmv_C_y = *mv;
367                         }
368                     }
369                 }
370             }
371 
372             offset_indx = currMB->SubMbPartWidth[mbPartIdx] >> 3;
373 
374             curr_ref_idx = currMB->ref_idx_L0[(block_y & 2) + (block_x >> 1)];
375 
376             if (avail_a && !(avail_b || avail_c))
377             {
378                 pmv_x = pmv_A_x;
379                 pmv_y = pmv_A_y;
380             }
381             else if (((curr_ref_idx == refIdxLXA) + (curr_ref_idx == refIdxLXB) + (curr_ref_idx == refIdxLXC)) == 1)
382             {
383                 if (curr_ref_idx == refIdxLXA)
384                 {
385                     pmv_x = pmv_A_x;
386                     pmv_y = pmv_A_y;
387                 }
388                 else if (curr_ref_idx == refIdxLXB)
389                 {
390                     pmv_x = pmv_B_x;
391                     pmv_y = pmv_B_y;
392                 }
393                 else
394                 {
395                     pmv_x = pmv_C_x;
396                     pmv_y = pmv_C_y;
397                 }
398             }
399             else
400             {
401                 pmv_x = AVC_MEDIAN(pmv_A_x, pmv_B_x, pmv_C_x);
402                 pmv_y = AVC_MEDIAN(pmv_A_y, pmv_B_y, pmv_C_y);
403             }
404 
405             /* overwrite if special case */
406             if (currMB->NumMbPart == 2)
407             {
408                 if (currMB->MbPartWidth == 16)
409                 {
410                     if (mbPartIdx == 0)
411                     {
412                         if (refIdxLXB == curr_ref_idx)
413                         {
414                             pmv_x = pmv_B_x;
415                             pmv_y = pmv_B_y;
416                         }
417                     }
418                     else if (refIdxLXA == curr_ref_idx)
419                     {
420                         pmv_x = pmv_A_x;
421                         pmv_y = pmv_A_y;
422                     }
423                 }
424                 else
425                 {
426                     if (mbPartIdx == 0)
427                     {
428                         if (refIdxLXA == curr_ref_idx)
429                         {
430                             pmv_x = pmv_A_x;
431                             pmv_y = pmv_A_y;
432                         }
433                     }
434                     else if (refIdxLXC == curr_ref_idx)
435                     {
436                         pmv_x = pmv_C_x;
437                         pmv_y = pmv_C_y;
438                     }
439                 }
440             }
441 
442             mv = (int16*)(currMB->mvL0 + block_x + (block_y << 2));
443 
444             if (encFlag) /* calculate residual MV video->mvd_l0 */
445             {
446                 video->mvd_l0[mbPartIdx][subMbPartIdx][0] = *mv++ - pmv_x;
447                 video->mvd_l0[mbPartIdx][subMbPartIdx][1] = *mv++ - pmv_y;
448             }
449             else    /* calculate original MV currMB->mvL0 */
450             {
451                 pmv_x += video->mvd_l0[mbPartIdx][subMbPartIdx][0];
452                 pmv_y += video->mvd_l0[mbPartIdx][subMbPartIdx][1];
453 
454                 for (i = 0; i < nmSubMbHeight; i++)
455                 {
456                     for (j = 0; j < nmSubMbWidth; j++)
457                     {
458                         *mv++ = pmv_x;
459                         *mv++ = pmv_y;
460                     }
461                     mv += (8 - (j << 1));
462                 }
463             }
464         }
465         offset_MbPart_indx = currMB->MbPartWidth >> 4;
466 
467     }
468 }
469 
470 
471