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