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