• 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 "oscl_mem.h"
19 #include "avcenc_lib.h"
20 
21 
AVCEncodeSlice(AVCEncObject * encvid)22 AVCEnc_Status AVCEncodeSlice(AVCEncObject *encvid)
23 {
24     AVCEnc_Status status = AVCENC_SUCCESS;
25     AVCCommonObj *video = encvid->common;
26     AVCPicParamSet *pps = video->currPicParams;
27     AVCSliceHeader *sliceHdr = video->sliceHdr;
28     AVCMacroblock *currMB ;
29     AVCEncBitstream *stream = encvid->bitstream;
30     uint slice_group_id;
31     int CurrMbAddr, slice_type;
32 
33     slice_type = video->slice_type;
34 
35     /* set the first mb in slice */
36     video->mbNum = CurrMbAddr = sliceHdr->first_mb_in_slice;// * (1+video->MbaffFrameFlag);
37     slice_group_id = video->MbToSliceGroupMap[CurrMbAddr];
38 
39     video->mb_skip_run = 0;
40 
41     /* while loop , see subclause 7.3.4 */
42     while (1)
43     {
44         video->mbNum = CurrMbAddr;
45         currMB = video->currMB = &(video->mblock[CurrMbAddr]);
46         currMB->slice_id = video->slice_id;  // for deblocking
47 
48         video->mb_x = CurrMbAddr % video->PicWidthInMbs;
49         video->mb_y = CurrMbAddr / video->PicWidthInMbs;
50 
51         /* initialize QP for this MB here*/
52         /* calculate currMB->QPy */
53         RCInitMBQP(encvid);
54 
55         /* check the availability of neighboring macroblocks */
56         InitNeighborAvailability(video, CurrMbAddr);
57 
58         /* Assuming that InitNeighborAvailability has been called prior to this function */
59         video->intraAvailA = video->intraAvailB = video->intraAvailC = video->intraAvailD = 0;
60         /* this is necessary for all subsequent intra search */
61 
62         if (!video->currPicParams->constrained_intra_pred_flag)
63         {
64             video->intraAvailA = video->mbAvailA;
65             video->intraAvailB = video->mbAvailB;
66             video->intraAvailC = video->mbAvailC;
67             video->intraAvailD = video->mbAvailD;
68         }
69         else
70         {
71             if (video->mbAvailA)
72             {
73                 video->intraAvailA = video->mblock[video->mbAddrA].mb_intra;
74             }
75             if (video->mbAvailB)
76             {
77                 video->intraAvailB = video->mblock[video->mbAddrB].mb_intra ;
78             }
79             if (video->mbAvailC)
80             {
81                 video->intraAvailC = video->mblock[video->mbAddrC].mb_intra;
82             }
83             if (video->mbAvailD)
84             {
85                 video->intraAvailD = video->mblock[video->mbAddrD].mb_intra;
86             }
87         }
88 
89         /* encode_one_macroblock() */
90         status = EncodeMB(encvid);
91         if (status != AVCENC_SUCCESS)
92         {
93             break;
94         }
95 
96         /* go to next MB */
97         CurrMbAddr++;
98 
99         while ((uint)video->MbToSliceGroupMap[CurrMbAddr] != slice_group_id &&
100                 (uint)CurrMbAddr < video->PicSizeInMbs)
101         {
102             CurrMbAddr++;
103         }
104 
105         if ((uint)CurrMbAddr >= video->PicSizeInMbs)
106         {
107             /* end of slice, return, but before that check to see if there are other slices
108             to be encoded. */
109             encvid->currSliceGroup++;
110             if (encvid->currSliceGroup > (int)pps->num_slice_groups_minus1) /* no more slice group */
111             {
112                 status = AVCENC_PICTURE_READY;
113                 break;
114             }
115             else
116             {
117                 /* find first_mb_num for the next slice */
118                 CurrMbAddr = 0;
119                 while (video->MbToSliceGroupMap[CurrMbAddr] != encvid->currSliceGroup &&
120                         (uint)CurrMbAddr < video->PicSizeInMbs)
121                 {
122                     CurrMbAddr++;
123                 }
124                 if ((uint)CurrMbAddr >= video->PicSizeInMbs)
125                 {
126                     status = AVCENC_SLICE_EMPTY; /* error, one slice group has no MBs in it */
127                 }
128 
129                 video->mbNum = CurrMbAddr;
130                 status = AVCENC_SUCCESS;
131                 break;
132             }
133         }
134     }
135 
136     if (video->mb_skip_run > 0)
137     {
138         /* write skip_run */
139         if (slice_type != AVC_I_SLICE && slice_type != AVC_SI_SLICE)
140         {
141             ue_v(stream, video->mb_skip_run);
142             video->mb_skip_run = 0;
143         }
144         else    /* shouldn't happen */
145         {
146             status = AVCENC_FAIL;
147         }
148     }
149 
150     return status;
151 }
152 
153 
EncodeMB(AVCEncObject * encvid)154 AVCEnc_Status EncodeMB(AVCEncObject *encvid)
155 {
156     AVCEnc_Status status = AVCENC_SUCCESS;
157     AVCCommonObj *video = encvid->common;
158     AVCPictureData *currPic = video->currPic;
159     AVCFrameIO  *currInput = encvid->currInput;
160     AVCMacroblock *currMB = video->currMB;
161     AVCMacroblock *MB_A, *MB_B;
162     AVCEncBitstream *stream = encvid->bitstream;
163     AVCRateControl *rateCtrl = encvid->rateCtrl;
164     uint8 *cur, *curL, *curCb, *curCr;
165     uint8 *orgL, *orgCb, *orgCr, *org4;
166     int CurrMbAddr = video->mbNum;
167     int picPitch = currPic->pitch;
168     int orgPitch = currInput->pitch;
169     int x_position = (video->mb_x << 4);
170     int y_position = (video->mb_y << 4);
171     int offset;
172     int b8, b4, blkidx;
173     AVCResidualType  resType;
174     int slice_type;
175     int numcoeff; /* output from residual_block_cavlc */
176     int cost16, cost8;
177 
178     int num_bits, start_mb_bits, start_text_bits;
179 
180     slice_type = video->slice_type;
181 
182     /* now, point to the reconstructed frame */
183     offset = y_position * picPitch + x_position;
184     curL = currPic->Sl + offset;
185     orgL = currInput->YCbCr[0] + offset;
186     offset = (offset + x_position) >> 2;
187     curCb = currPic->Scb + offset;
188     curCr = currPic->Scr + offset;
189     orgCb = currInput->YCbCr[1] + offset;
190     orgCr = currInput->YCbCr[2] + offset;
191 
192     if (orgPitch != picPitch)
193     {
194         offset = y_position * (orgPitch - picPitch);
195         orgL += offset;
196         offset >>= 2;
197         orgCb += offset;
198         orgCr += offset;
199     }
200 
201     /******* determine MB prediction mode *******/
202     if (encvid->intraSearch[CurrMbAddr])
203     {
204         MBIntraSearch(encvid, CurrMbAddr, curL, picPitch);
205     }
206     /******* This part should be determined somehow ***************/
207     if (currMB->mbMode == AVC_I_PCM)
208     {
209         /* write down mb_type and PCM data */
210         /* and copy from currInput to currPic */
211         status = EncodeIntraPCM(encvid);
212 
213 
214         return status;
215     }
216 
217     /****** for intra prediction, pred is already done *******/
218     /****** for I4, the recon is ready and Xfrm coefs are ready to be encoded *****/
219 
220     //RCCalculateMAD(encvid,currMB,orgL,orgPitch); // no need to re-calculate MAD for Intra
221     // not used since totalSAD is used instead
222 
223     /* compute the prediction */
224     /* output is video->pred_block */
225     if (!currMB->mb_intra)
226     {
227         AVCMBMotionComp(encvid, video); /* perform prediction and residue calculation */
228         /* we can do the loop here and call dct_luma */
229         video->pred_pitch = picPitch;
230         currMB->CBP = 0;
231         cost16 = 0;
232         cur = curL;
233         org4 = orgL;
234 
235         for (b8 = 0; b8 < 4; b8++)
236         {
237             cost8 = 0;
238 
239             for (b4 = 0; b4 < 4; b4++)
240             {
241                 blkidx = blkIdx2blkXY[b8][b4];
242                 video->pred_block = cur;
243                 numcoeff = dct_luma(encvid, blkidx, cur, org4, &cost8);
244                 currMB->nz_coeff[blkidx] = numcoeff;
245                 if (numcoeff)
246                 {
247                     video->cbp4x4 |= (1 << blkidx);
248                     currMB->CBP |= (1 << b8);
249                 }
250 
251                 if (b4&1)
252                 {
253                     cur += ((picPitch << 2) - 4);
254                     org4 += ((orgPitch << 2) - 4);
255                 }
256                 else
257                 {
258                     cur += 4;
259                     org4 += 4;
260                 }
261             }
262 
263             /* move the IDCT part out of dct_luma to accommodate the check
264                for coeff_cost. */
265 
266             if ((currMB->CBP&(1 << b8)) && (cost8 <= _LUMA_COEFF_COST_))
267             {
268                 cost8 = 0; // reset it
269 
270                 currMB->CBP ^= (1 << b8);
271                 blkidx = blkIdx2blkXY[b8][0];
272 
273                 currMB->nz_coeff[blkidx] = 0;
274                 currMB->nz_coeff[blkidx+1] = 0;
275                 currMB->nz_coeff[blkidx+4] = 0;
276                 currMB->nz_coeff[blkidx+5] = 0;
277             }
278 
279             cost16 += cost8;
280 
281             if (b8&1)
282             {
283                 cur -= 8;
284                 org4 -= 8;
285             }
286             else
287             {
288                 cur += (8 - (picPitch << 3));
289                 org4 += (8 - (orgPitch << 3));
290             }
291         }
292 
293         /* after the whole MB, we do another check for coeff_cost */
294         if ((currMB->CBP&0xF) && (cost16 <= _LUMA_MB_COEFF_COST_))
295         {
296             currMB->CBP = 0;  // reset it to zero
297             oscl_memset(currMB->nz_coeff, 0, sizeof(uint8)*16);
298         }
299 
300         // now we do IDCT
301         MBInterIdct(video, curL, currMB, picPitch);
302 
303 //      video->pred_block = video->pred + 256;
304     }
305     else    /* Intra prediction */
306     {
307         encvid->numIntraMB++;
308 
309         if (currMB->mbMode == AVC_I16) /* do prediction for the whole macroblock */
310         {
311             currMB->CBP = 0;
312             /* get the prediction from encvid->pred_i16 */
313             dct_luma_16x16(encvid, curL, orgL);
314         }
315         video->pred_block = encvid->pred_ic[currMB->intra_chroma_pred_mode];
316     }
317 
318     /* chrominance */
319     /* not need to do anything, the result is in encvid->pred_ic
320     chroma dct must be aware that prediction block can come from either intra or inter. */
321 
322     dct_chroma(encvid, curCb, orgCb, 0);
323 
324     dct_chroma(encvid, curCr, orgCr, 1);
325 
326 
327     /* 4.1 if there's nothing in there, video->mb_skip_run++ */
328     /* 4.2 if coded, check if there is a run of skipped MB, encodes it,
329             set video->QPyprev = currMB->QPy; */
330 
331     /* 5. vlc encode */
332 
333     /* check for skipped macroblock, INTER only */
334     if (!currMB->mb_intra)
335     {
336         /* decide whether this MB (for inter MB) should be skipped if there's nothing left. */
337         if (!currMB->CBP && currMB->NumMbPart == 1 && currMB->QPy == video->QPy)
338         {
339             if (currMB->MBPartPredMode[0][0] == AVC_Pred_L0 && currMB->ref_idx_L0[0] == 0)
340             {
341                 MB_A = &video->mblock[video->mbAddrA];
342                 MB_B = &video->mblock[video->mbAddrB];
343 
344                 if (!video->mbAvailA || !video->mbAvailB)
345                 {
346                     if (currMB->mvL0[0] == 0) /* both mv components are zeros.*/
347                     {
348                         currMB->mbMode = AVC_SKIP;
349                         video->mvd_l0[0][0][0] = 0;
350                         video->mvd_l0[0][0][1] = 0;
351                     }
352                 }
353                 else
354                 {
355                     if ((MB_A->ref_idx_L0[1] == 0 && MB_A->mvL0[3] == 0) ||
356                             (MB_B->ref_idx_L0[2] == 0 && MB_B->mvL0[12] == 0))
357                     {
358                         if (currMB->mvL0[0] == 0) /* both mv components are zeros.*/
359                         {
360                             currMB->mbMode = AVC_SKIP;
361                             video->mvd_l0[0][0][0] = 0;
362                             video->mvd_l0[0][0][1] = 0;
363                         }
364                     }
365                     else if (video->mvd_l0[0][0][0] == 0 && video->mvd_l0[0][0][1] == 0)
366                     {
367                         currMB->mbMode = AVC_SKIP;
368                     }
369                 }
370             }
371 
372             if (currMB->mbMode == AVC_SKIP)
373             {
374                 video->mb_skip_run++;
375 
376                 /* set parameters */
377                 /* not sure whether we need the followings */
378                 if (slice_type == AVC_P_SLICE)
379                 {
380                     currMB->mbMode = AVC_SKIP;
381                     currMB->MbPartWidth = currMB->MbPartHeight = 16;
382                     currMB->MBPartPredMode[0][0] = AVC_Pred_L0;
383                     currMB->NumMbPart = 1;
384                     currMB->NumSubMbPart[0] = currMB->NumSubMbPart[1] =
385                                                   currMB->NumSubMbPart[2] = currMB->NumSubMbPart[3] = 1;
386                     currMB->SubMbPartWidth[0] = currMB->SubMbPartWidth[1] =
387                                                     currMB->SubMbPartWidth[2] = currMB->SubMbPartWidth[3] = currMB->MbPartWidth;
388                     currMB->SubMbPartHeight[0] = currMB->SubMbPartHeight[1] =
389                                                      currMB->SubMbPartHeight[2] = currMB->SubMbPartHeight[3] = currMB->MbPartHeight;
390 
391                 }
392                 else if (slice_type == AVC_B_SLICE)
393                 {
394                     currMB->mbMode = AVC_SKIP;
395                     currMB->MbPartWidth = currMB->MbPartHeight = 8;
396                     currMB->MBPartPredMode[0][0] = AVC_Direct;
397                     currMB->NumMbPart = -1;
398                 }
399 
400                 /* for skipped MB, always look at the first entry in RefPicList */
401                 currMB->RefIdx[0] = currMB->RefIdx[1] =
402                                         currMB->RefIdx[2] = currMB->RefIdx[3] = video->RefPicList0[0]->RefIdx;
403 
404                 /* do not return yet, need to do some copies */
405             }
406         }
407     }
408     /* non-skipped MB */
409 
410 
411     /************* START ENTROPY CODING *************************/
412 
413     start_mb_bits = 32 + (encvid->bitstream->write_pos << 3) - encvid->bitstream->bit_left;
414 
415     /* encode mb_type, mb_pred, sub_mb_pred, CBP */
416     if (slice_type != AVC_I_SLICE && slice_type != AVC_SI_SLICE && currMB->mbMode != AVC_SKIP)
417     {
418         //if(!pps->entropy_coding_mode_flag)  ALWAYS true
419         {
420             ue_v(stream, video->mb_skip_run);
421             video->mb_skip_run = 0;
422         }
423     }
424 
425     if (currMB->mbMode != AVC_SKIP)
426     {
427         status = EncodeMBHeader(currMB, encvid);
428         if (status != AVCENC_SUCCESS)
429         {
430             return status;
431         }
432     }
433 
434     start_text_bits = 32 + (encvid->bitstream->write_pos << 3) - encvid->bitstream->bit_left;
435 
436     /**** now decoding part *******/
437     resType = AVC_Luma;
438 
439     /* DC transform for luma I16 mode */
440     if (currMB->mbMode == AVC_I16)
441     {
442         /* vlc encode level/run */
443         status = enc_residual_block(encvid, AVC_Intra16DC, encvid->numcoefdc, currMB);
444         if (status != AVCENC_SUCCESS)
445         {
446             return status;
447         }
448         resType = AVC_Intra16AC;
449     }
450 
451     /* VLC encoding for luma */
452     for (b8 = 0; b8 < 4; b8++)
453     {
454         if (currMB->CBP&(1 << b8))
455         {
456             for (b4 = 0; b4 < 4; b4++)
457             {
458                 /* vlc encode level/run */
459                 status = enc_residual_block(encvid, resType, (b8 << 2) + b4, currMB);
460                 if (status != AVCENC_SUCCESS)
461                 {
462                     return status;
463                 }
464             }
465         }
466     }
467 
468     /* chroma */
469     if (currMB->CBP & (3 << 4)) /* chroma DC residual present */
470     {
471         for (b8 = 0; b8 < 2; b8++) /* for iCbCr */
472         {
473             /* vlc encode level/run */
474             status = enc_residual_block(encvid, AVC_ChromaDC, encvid->numcoefcdc[b8] + (b8 << 3), currMB);
475             if (status != AVCENC_SUCCESS)
476             {
477                 return status;
478             }
479         }
480     }
481 
482     if (currMB->CBP & (2 << 4))
483     {
484         /* AC part */
485         for (b8 = 0; b8 < 2; b8++) /* for iCbCr */
486         {
487             for (b4 = 0; b4 < 4; b4++)  /* for each block inside Cb or Cr */
488             {
489                 /* vlc encode level/run */
490                 status = enc_residual_block(encvid, AVC_ChromaAC, 16 + (b8 << 2) + b4, currMB);
491                 if (status != AVCENC_SUCCESS)
492                 {
493                     return status;
494                 }
495             }
496         }
497     }
498 
499 
500     num_bits = 32 + (encvid->bitstream->write_pos << 3) - encvid->bitstream->bit_left;
501 
502     RCPostMB(video, rateCtrl, start_text_bits - start_mb_bits,
503              num_bits - start_text_bits);
504 
505 //  num_bits -= start_mb_bits;
506 //  fprintf(fdebug,"MB #%d: %d bits\n",CurrMbAddr,num_bits);
507 //  fclose(fdebug);
508     return status;
509 }
510 
511 /* copy the content from predBlock back to the reconstructed YUV frame */
Copy_MB(uint8 * curL,uint8 * curCb,uint8 * curCr,uint8 * predBlock,int picPitch)512 void Copy_MB(uint8 *curL, uint8 *curCb, uint8 *curCr, uint8 *predBlock, int picPitch)
513 {
514     int j, offset;
515     uint32 *dst, *dst2, *src;
516 
517     dst = (uint32*)curL;
518     src = (uint32*)predBlock;
519 
520     offset = (picPitch - 16) >> 2;
521 
522     for (j = 0; j < 16; j++)
523     {
524         *dst++ = *src++;
525         *dst++ = *src++;
526         *dst++ = *src++;
527         *dst++ = *src++;
528 
529         dst += offset;
530     }
531 
532     dst = (uint32*)curCb;
533     dst2 = (uint32*)curCr;
534     offset >>= 1;
535 
536     for (j = 0; j < 8; j++)
537     {
538         *dst++ = *src++;
539         *dst++ = *src++;
540         *dst2++ = *src++;
541         *dst2++ = *src++;
542 
543         dst += offset;
544         dst2 += offset;
545     }
546     return ;
547 }
548 
549 /* encode mb_type, mb_pred, sub_mb_pred, CBP */
550 /* decide whether this MB (for inter MB) should be skipped */
EncodeMBHeader(AVCMacroblock * currMB,AVCEncObject * encvid)551 AVCEnc_Status EncodeMBHeader(AVCMacroblock *currMB, AVCEncObject *encvid)
552 {
553     AVCEnc_Status status = AVCENC_SUCCESS;
554     uint mb_type;
555     AVCCommonObj *video = encvid->common;
556     AVCEncBitstream *stream = encvid->bitstream;
557 
558     if (currMB->CBP > 47)   /* chroma CBP is 11 */
559     {
560         currMB->CBP -= 16;  /* remove the 5th bit from the right */
561     }
562 
563     mb_type = InterpretMBType(currMB, video->slice_type);
564 
565     status = ue_v(stream, mb_type);
566 
567     if (currMB->mbMode == AVC_P8 || currMB->mbMode == AVC_P8ref0)
568     {
569         status = sub_mb_pred(video, currMB, stream);
570     }
571     else
572     {
573         status = mb_pred(video, currMB, stream) ;
574     }
575 
576     if (currMB->mbMode != AVC_I16)
577     {
578         /* decode coded_block_pattern */
579         status = EncodeCBP(currMB, stream);
580     }
581 
582     /* calculate currMB->mb_qp_delta = currMB->QPy - video->QPyprev */
583     if (currMB->CBP > 0 || currMB->mbMode == AVC_I16)
584     {
585         status = se_v(stream, currMB->QPy - video->QPy);
586         video->QPy = currMB->QPy; /* = (video->QPyprev + currMB->mb_qp_delta + 52)%52; */
587         // no need video->QPc = currMB->QPc;
588     }
589     else
590     {
591         if (currMB->QPy != video->QPy) // current QP is not the same as previous QP
592         {
593             /* restore these values */
594             RCRestoreQP(currMB, video, encvid);
595         }
596     }
597 
598     return status;
599 }
600 
601 
602 /* inputs are mbMode, mb_intra, i16Mode, CBP, NumMbPart, MbPartWidth, MbPartHeight */
InterpretMBType(AVCMacroblock * currMB,int slice_type)603 uint InterpretMBType(AVCMacroblock *currMB, int slice_type)
604 {
605     int CBP_chrom;
606     int mb_type;// part1, part2, part3;
607 //  const static int MapParts2Type[2][3][3]={{{4,8,12},{10,6,14},{16,18,20}},
608 //  {{5,9,13},{11,7,15},{17,19,21}}};
609 
610     if (currMB->mb_intra)
611     {
612         if (currMB->mbMode == AVC_I4)
613         {
614             mb_type = 0;
615         }
616         else if (currMB->mbMode == AVC_I16)
617         {
618             CBP_chrom = (currMB->CBP & 0x30);
619             if (currMB->CBP&0xF)
620             {
621                 currMB->CBP |= 0xF;  /* either 0x0 or 0xF */
622                 mb_type = 13;
623             }
624             else
625             {
626                 mb_type = 1;
627             }
628             mb_type += (CBP_chrom >> 2) + currMB->i16Mode;
629         }
630         else /* if(currMB->mbMode == AVC_I_PCM) */
631         {
632             mb_type = 25;
633         }
634     }
635     else
636     {  /* P-MB *//* note that the order of the enum AVCMBMode cannot be changed
637         since we use it here. */
638         mb_type = currMB->mbMode - AVC_P16;
639     }
640 
641     if (slice_type == AVC_P_SLICE)
642     {
643         if (currMB->mb_intra)
644         {
645             mb_type += 5;
646         }
647     }
648     // following codes have not been tested yet, not needed.
649     /*  else if(slice_type == AVC_B_SLICE)
650         {
651             if(currMB->mbMode == AVC_BDirect16)
652             {
653                 mb_type = 0;
654             }
655             else if(currMB->mbMode == AVC_P16)
656             {
657                 mb_type = currMB->MBPartPredMode[0][0] + 1; // 1 or 2
658             }
659             else if(currMB->mbMode == AVC_P8)
660             {
661                 mb_type = 26;
662             }
663             else if(currMB->mbMode == AVC_P8ref0)
664             {
665                 mb_type = 27;
666             }
667             else
668             {
669                 part1 = currMB->mbMode - AVC_P16x8;
670                 part2 = currMB->MBPartPredMode[0][0];
671                 part3 = currMB->MBPartPredMode[1][0];
672                 mb_type = MapParts2Type[part1][part2][part3];
673             }
674         }
675 
676         if(slice_type == AVC_SI_SLICE)
677         {
678             mb_type++;
679         }
680     */
681     return (uint)mb_type;
682 }
683 
684 //const static int mbPart2raster[3][4] = {{0,0,0,0},{1,1,0,0},{1,0,1,0}};
685 
686 /* see subclause 7.3.5.1 */
mb_pred(AVCCommonObj * video,AVCMacroblock * currMB,AVCEncBitstream * stream)687 AVCEnc_Status mb_pred(AVCCommonObj *video, AVCMacroblock *currMB, AVCEncBitstream *stream)
688 {
689     AVCEnc_Status status = AVCENC_SUCCESS;
690     int mbPartIdx;
691     AVCSliceHeader *sliceHdr = video->sliceHdr;
692     int max_ref_idx;
693     uint code;
694 
695     if (currMB->mbMode == AVC_I4 || currMB->mbMode == AVC_I16)
696     {
697         if (currMB->mbMode == AVC_I4)
698         {
699             /* perform prediction to get the actual intra 4x4 pred mode */
700             EncodeIntra4x4Mode(video, currMB, stream);
701             /* output will be in currMB->i4Mode[4][4] */
702         }
703 
704         /* assume already set from MBPrediction() */
705         status = ue_v(stream, currMB->intra_chroma_pred_mode);
706     }
707     else if (currMB->MBPartPredMode[0][0] != AVC_Direct)
708     {
709 
710         oscl_memset(currMB->ref_idx_L0, 0, sizeof(int16)*4);
711 
712         /* see subclause 7.4.5.1 for the range of ref_idx_lX */
713         max_ref_idx = sliceHdr->num_ref_idx_l0_active_minus1;
714         /*      if(video->MbaffFrameFlag && currMB->mb_field_decoding_flag)
715                     max_ref_idx = 2*sliceHdr->num_ref_idx_l0_active_minus1 + 1;
716         */
717         /* decode ref index for L0 */
718         if (sliceHdr->num_ref_idx_l0_active_minus1 > 0)
719         {
720             for (mbPartIdx = 0; mbPartIdx < currMB->NumMbPart; mbPartIdx++)
721             {
722                 if (/*(sliceHdr->num_ref_idx_l0_active_minus1>0 || currMB->mb_field_decoding_flag) &&*/
723                     currMB->MBPartPredMode[mbPartIdx][0] != AVC_Pred_L1)
724                 {
725                     code = currMB->ref_idx_L0[mbPartIdx];
726                     status = te_v(stream, code, max_ref_idx);
727                 }
728             }
729         }
730 
731         /* see subclause 7.4.5.1 for the range of ref_idx_lX */
732         max_ref_idx = sliceHdr->num_ref_idx_l1_active_minus1;
733         /*      if(video->MbaffFrameFlag && currMB->mb_field_decoding_flag)
734                     max_ref_idx = 2*sliceHdr->num_ref_idx_l1_active_minus1 + 1;
735         */
736         /* decode ref index for L1 */
737         if (sliceHdr->num_ref_idx_l1_active_minus1 > 0)
738         {
739             for (mbPartIdx = 0; mbPartIdx < currMB->NumMbPart; mbPartIdx++)
740             {
741                 if (/*(sliceHdr->num_ref_idx_l1_active_minus1>0 || currMB->mb_field_decoding_flag) &&*/
742                     currMB->MBPartPredMode[mbPartIdx][0] != AVC_Pred_L0)
743                 {
744                     status = te_v(stream, currMB->ref_idx_L1[mbPartIdx], max_ref_idx);
745                 }
746             }
747         }
748 
749         /* encode mvd_l0 */
750         for (mbPartIdx = 0; mbPartIdx < currMB->NumMbPart; mbPartIdx++)
751         {
752             if (currMB->MBPartPredMode[mbPartIdx][0] != AVC_Pred_L1)
753             {
754                 status = se_v(stream, video->mvd_l0[mbPartIdx][0][0]);
755                 status = se_v(stream, video->mvd_l0[mbPartIdx][0][1]);
756             }
757         }
758         /* encode mvd_l1 */
759         for (mbPartIdx = 0; mbPartIdx < currMB->NumMbPart; mbPartIdx++)
760         {
761             if (currMB->MBPartPredMode[mbPartIdx][0] != AVC_Pred_L0)
762             {
763                 status = se_v(stream, video->mvd_l1[mbPartIdx][0][0]);
764                 status = se_v(stream, video->mvd_l1[mbPartIdx][0][1]);
765             }
766         }
767     }
768 
769     return status;
770 }
771 
772 /* see subclause 7.3.5.2 */
sub_mb_pred(AVCCommonObj * video,AVCMacroblock * currMB,AVCEncBitstream * stream)773 AVCEnc_Status sub_mb_pred(AVCCommonObj *video, AVCMacroblock *currMB, AVCEncBitstream *stream)
774 {
775     AVCEnc_Status status = AVCENC_SUCCESS;
776     int mbPartIdx, subMbPartIdx;
777     AVCSliceHeader *sliceHdr = video->sliceHdr;
778     uint max_ref_idx;
779     uint slice_type = video->slice_type;
780     uint sub_mb_type[4];
781 
782     /* this should move somewhere else where we don't have to make this check */
783     if (currMB->mbMode == AVC_P8ref0)
784     {
785         oscl_memset(currMB->ref_idx_L0, 0, sizeof(int16)*4);
786     }
787 
788     /* we have to check the values to make sure they are valid  */
789     /* assign values to currMB->sub_mb_type[] */
790     if (slice_type == AVC_P_SLICE)
791     {
792         InterpretSubMBTypeP(currMB, sub_mb_type);
793     }
794     /* no need to check for B-slice
795         else if(slice_type == AVC_B_SLICE)
796         {
797             InterpretSubMBTypeB(currMB,sub_mb_type);
798         }*/
799 
800     for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
801     {
802         status = ue_v(stream, sub_mb_type[mbPartIdx]);
803     }
804 
805     /* see subclause 7.4.5.1 for the range of ref_idx_lX */
806     max_ref_idx = sliceHdr->num_ref_idx_l0_active_minus1;
807     /*  if(video->MbaffFrameFlag && currMB->mb_field_decoding_flag)
808             max_ref_idx = 2*sliceHdr->num_ref_idx_l0_active_minus1 + 1; */
809 
810     for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
811     {
812         if ((sliceHdr->num_ref_idx_l0_active_minus1 > 0 /*|| currMB->mb_field_decoding_flag*/) &&
813                 currMB->mbMode != AVC_P8ref0 && /*currMB->subMbMode[mbPartIdx]!=AVC_BDirect8 &&*/
814                 currMB->MBPartPredMode[mbPartIdx][0] != AVC_Pred_L1)
815         {
816             status = te_v(stream, currMB->ref_idx_L0[mbPartIdx], max_ref_idx);
817         }
818         /* used in deblocking */
819         currMB->RefIdx[mbPartIdx] = video->RefPicList0[currMB->ref_idx_L0[mbPartIdx]]->RefIdx;
820     }
821     /* see subclause 7.4.5.1 for the range of ref_idx_lX */
822     max_ref_idx = sliceHdr->num_ref_idx_l1_active_minus1;
823     /*  if(video->MbaffFrameFlag && currMB->mb_field_decoding_flag)
824             max_ref_idx = 2*sliceHdr->num_ref_idx_l1_active_minus1 + 1;*/
825 
826     if (sliceHdr->num_ref_idx_l1_active_minus1 > 0)
827     {
828         for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
829         {
830             if (/*(sliceHdr->num_ref_idx_l1_active_minus1>0 || currMB->mb_field_decoding_flag) &&*/
831                 /*currMB->subMbMode[mbPartIdx]!=AVC_BDirect8 &&*/
832                 currMB->MBPartPredMode[mbPartIdx][0] != AVC_Pred_L0)
833             {
834                 status = te_v(stream, currMB->ref_idx_L1[mbPartIdx], max_ref_idx);
835             }
836         }
837     }
838 
839     for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
840     {
841         if (/*currMB->subMbMode[mbPartIdx]!=AVC_BDirect8 &&*/
842             currMB->MBPartPredMode[mbPartIdx][0] != AVC_Pred_L1)
843         {
844             for (subMbPartIdx = 0; subMbPartIdx < currMB->NumSubMbPart[mbPartIdx]; subMbPartIdx++)
845             {
846                 status = se_v(stream, video->mvd_l0[mbPartIdx][subMbPartIdx][0]);
847                 status = se_v(stream, video->mvd_l0[mbPartIdx][subMbPartIdx][1]);
848             }
849         }
850     }
851 
852     for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
853     {
854         if (/*currMB->subMbMode[mbPartIdx]!=AVC_BDirect8 &&*/
855             currMB->MBPartPredMode[mbPartIdx][0] != AVC_Pred_L0)
856         {
857             for (subMbPartIdx = 0; subMbPartIdx < currMB->NumSubMbPart[mbPartIdx]; subMbPartIdx++)
858             {
859                 status = se_v(stream, video->mvd_l1[mbPartIdx][subMbPartIdx][0]);
860                 status = se_v(stream, video->mvd_l1[mbPartIdx][subMbPartIdx][1]);
861             }
862         }
863     }
864 
865     return status;
866 }
867 
868 /* input is mblock->sub_mb_type[] */
InterpretSubMBTypeP(AVCMacroblock * mblock,uint * sub_mb_type)869 void InterpretSubMBTypeP(AVCMacroblock *mblock, uint *sub_mb_type)
870 {
871     int i;
872     /* see enum AVCMBType declaration */
873     /*const static AVCSubMBMode map2subMbMode[4] = {AVC_8x8,AVC_8x4,AVC_4x8,AVC_4x4};
874     const static int map2subPartWidth[4] = {8,8,4,4};
875     const static int map2subPartHeight[4] = {8,4,8,4};
876     const static int map2numSubPart[4] = {1,2,2,4};*/
877 
878     for (i = 0; i < 4 ; i++)
879     {
880         sub_mb_type[i] = mblock->subMbMode[i] - AVC_8x8;
881     }
882 
883     return ;
884 }
885 
InterpretSubMBTypeB(AVCMacroblock * mblock,uint * sub_mb_type)886 void InterpretSubMBTypeB(AVCMacroblock *mblock, uint *sub_mb_type)
887 {
888     int i;
889     /* see enum AVCMBType declaration */
890     /*  const static AVCSubMBMode map2subMbMode[13] = {AVC_BDirect8,AVC_8x8,AVC_8x8,
891             AVC_8x8,AVC_8x4,AVC_4x8,AVC_8x4,AVC_4x8,AVC_8x4,AVC_4x8,AVC_4x4,AVC_4x4,AVC_4x4};
892         const static int map2subPartWidth[13] = {4,8,8,8,8,4,8,4,8,4,4,4,4};
893         const static int map2subPartHeight[13] = {4,8,8,8,4,8,4,8,4,8,4,4,4};
894         const static int map2numSubPart[13] = {4,1,1,1,2,2,2,2,2,2,4,4,4};
895         const static int map2predMode[13] = {3,0,1,2,0,0,1,1,2,2,0,1,2};*/
896 
897     for (i = 0; i < 4 ; i++)
898     {
899         if (mblock->subMbMode[i] == AVC_BDirect8)
900         {
901             sub_mb_type[i] = 0;
902         }
903         else if (mblock->subMbMode[i] == AVC_8x8)
904         {
905             sub_mb_type[i] = 1 + mblock->MBPartPredMode[i][0];
906         }
907         else if (mblock->subMbMode[i] == AVC_4x4)
908         {
909             sub_mb_type[i] = 10 + mblock->MBPartPredMode[i][0];
910         }
911         else
912         {
913             sub_mb_type[i] = 4 + (mblock->MBPartPredMode[i][0] << 1) + (mblock->subMbMode[i] - AVC_8x4);
914         }
915     }
916 
917     return ;
918 }
919 
920 /* see subclause 8.3.1 */
EncodeIntra4x4Mode(AVCCommonObj * video,AVCMacroblock * currMB,AVCEncBitstream * stream)921 AVCEnc_Status EncodeIntra4x4Mode(AVCCommonObj *video, AVCMacroblock *currMB, AVCEncBitstream *stream)
922 {
923     int intra4x4PredModeA = 0;
924     int intra4x4PredModeB, predIntra4x4PredMode;
925     int component, SubBlock_indx, block_x, block_y;
926     int dcOnlyPredictionFlag;
927     uint    flag;
928     int     rem = 0;
929     int     mode;
930     int bindx = 0;
931 
932     for (component = 0; component < 4; component++) /* partition index */
933     {
934         block_x = ((component & 1) << 1);
935         block_y = ((component >> 1) << 1);
936 
937         for (SubBlock_indx = 0; SubBlock_indx < 4; SubBlock_indx++) /* sub-partition index */
938         {
939             dcOnlyPredictionFlag = 0;
940             if (block_x > 0)
941             {
942                 intra4x4PredModeA = currMB->i4Mode[(block_y << 2) + block_x - 1 ];
943             }
944             else
945             {
946                 if (video->intraAvailA)
947                 {
948                     if (video->mblock[video->mbAddrA].mbMode == AVC_I4)
949                     {
950                         intra4x4PredModeA = video->mblock[video->mbAddrA].i4Mode[(block_y << 2) + 3];
951                     }
952                     else
953                     {
954                         intra4x4PredModeA = AVC_I4_DC;
955                     }
956                 }
957                 else
958                 {
959                     dcOnlyPredictionFlag = 1;
960                 }
961             }
962 
963             if (block_y > 0)
964             {
965                 intra4x4PredModeB = currMB->i4Mode[((block_y-1) << 2) + block_x];
966             }
967             else
968             {
969                 if (video->intraAvailB)
970                 {
971                     if (video->mblock[video->mbAddrB].mbMode == AVC_I4)
972                     {
973                         intra4x4PredModeB = video->mblock[video->mbAddrB].i4Mode[(3 << 2) + block_x];
974                     }
975                     else
976                     {
977                         intra4x4PredModeB = AVC_I4_DC;
978                     }
979                 }
980                 else
981                 {
982                     dcOnlyPredictionFlag = 1;
983                 }
984             }
985 
986             if (dcOnlyPredictionFlag)
987             {
988                 intra4x4PredModeA = intra4x4PredModeB = AVC_I4_DC;
989             }
990 
991             predIntra4x4PredMode = AVC_MIN(intra4x4PredModeA, intra4x4PredModeB);
992 
993             flag = 0;
994             mode = currMB->i4Mode[(block_y<<2)+block_x];
995 
996             if (mode == (AVCIntra4x4PredMode)predIntra4x4PredMode)
997             {
998                 flag = 1;
999             }
1000             else if (mode < predIntra4x4PredMode)
1001             {
1002                 rem = mode;
1003             }
1004             else
1005             {
1006                 rem = mode - 1;
1007             }
1008 
1009             BitstreamWrite1Bit(stream, flag);
1010 
1011             if (!flag)
1012             {
1013                 BitstreamWriteBits(stream, 3, rem);
1014             }
1015 
1016             bindx++;
1017             block_y += (SubBlock_indx & 1) ;
1018             block_x += (1 - 2 * (SubBlock_indx & 1)) ;
1019         }
1020     }
1021 
1022     return AVCENC_SUCCESS;
1023 }
1024 
1025 
1026 
1027