No 3 encodeoneslice Deblock Mb Relation of Functions
No. 3 encode_one_slice() Deblock. Mb() • Relation of Functions Encode_one_slice( ) Code_a_picture( ) Deblock. Frame() Deblock. Mb()
H. 264 Code Tracing encode_one_slice() No. 3 9762642 陳則伊
Introduction-caller and main function • “slice. c” • Caller: code_a_picture() • Main function of encode_one_slice(): – Encode a slice group – Execute PAFF / MBAFF mode
Introduction-input and output • Input: – int Slice. Group. Id – Picture *pic – int Total. Coded. MBs • Output: – int Number. Of. Coded. MBs
Local Variables 1) 2) 3) 4) 5) 6) 7) Boolean end_of_slice = FALSE; Boolean recode_macroblock; int len; //# of bits of header used in a slice int Number. Of. Coded. MBs = 0; //return int Current. Mb. Addr; double Frame. RDCost = DBL_MAX; double Field. RDCost = DBL_MAX;
Initializations • Current. Mb. Addr = Fmo. Get. First. Macroblock. In. Slice (Slice. Group. Id); • init_slice (Current. Mb. Addr); • Set. Lagrangian. Multipliers(); • len = start_slice ();
Main function code(1) • Loop over MBs in a slice while (end_of_slice == FALSE) { -Encode by PAFF mode -Encode by MBAFF mode } terminate_slice(……); return Number. Of. Coded. MBs;
Main function code(2) • Calculate the quantization offset parameters if (img->Adaptive. Rounding && input->Adapt. Rnd. Period && (img->current_mb_nr % input->Adapt. Rnd. Period == 0)) { Calculate. Offset. Param(); if(input->Transform 8 x 8 Mode) { Calculate. Offset 8 Param(); } }
Main function code(3)-PAFF • Use PAFF mode if (!img->Mbaff. Frame. Flag) { recode_macroblock = FALSE; rdopt = &rddata_top_frame_mb; start_macroblock (Current. Mb. Addr, FALSE); encode_one_macroblock (); write_one_macroblock (1); terminate_macroblock (&end_of_slice, &recode_macroblock); ……
Main function code(4)-PAFF • If MB don’t need to be recoded …… if (recode_macroblock == FALSE) { Current. Mb. Addr = Fmo. Get. Next. MBNr (Current. Mb. Addr); if (Current. Mb. Addr == -1) // end of slice end_of_slice = TRUE; } …… Number. Of. Coded. MBs++; proceed 2 next. Macroblock ();
Main function code(5)-PAFF • If MB need to be recoded …… else{ img->current_mb_nr = Fmo. Get. Previous. MBNr(img->current_mb_nr); if(img->current_mb_nr == -1 ) error (errortext, 300); } } // end of PAFF mode
Main function code(6)-MBAFF • Check whether it is frame mode else{ //Use MBAFF mode if (input->Mb. Interlace == ADAPTIVE_CODING || input->Mb. Interlace == FRAME_MB_PAIR_CODING) { -Encode top MB as frame MB -Encode bottom MB as frame MB } ……
Main function code(7)-MBAFF • Encode top MB as frame MB – Set top MB coded as frame MB recode_macroblock = FALSE; img->field_mode = 0; // MB coded as frame img->top_field = 0; // Set top field to 0 – Rate control img->write_macroblock = 0; img->bot_MB = 0; – Encode one MB start_macroblock (Current. Mb. Addr, FALSE); rdopt = &rddata_top_frame_mb; // store data in top frame MB encode_one_macroblock (); // code the MB as frame MB Frame. RDCost = rdopt->min_rdcost;
Main function code(8)-MBAFF • Encode bottom MB as frame MB – Set bottom MB coded as frame MB img->field_mode = 0; // MB coded as frame MB – Rate control img->bot_MB = 1; – Encode one MB start_macroblock (Current. Mb. Addr+1, FALSE); rdopt = &rddata_bot_frame_mb; // store data in bottom frame MB encode_one_macroblock (); // code the MB as frame MB Frame. RDCost += rdopt->min_rdcost;
Main function code(9)-MBAFF • Check whether it is field mode if ((input->Mb. Interlace == ADAPTIVE_CODING) || (input->Mb. Interlace == FIELD_CODING)) { -Encode top MB as field MB -Encode bottom MB as field MB }
Main function code(10)-MBAFF • Encode top MB as field MB – Set top MB coded as field MB img->field_mode = 1; // MB coded as field img->top_field = 1; // Set top field to 1 – Rate control img->bot_MB = 0; – Encode one MB start_macroblock (Current. Mb. Addr, TRUE); rdopt = &rddata_top_field_mb; // store data in top field MB encode_one_macroblock (); // code the MB as field MB Field. RDCost = rdopt->min_rdcost;
Main function code(11)-MBAFF • Encode bottom MB as field MB – Set bottom MB coded as field MB img->top_field = 0; // Set top field to 0 – Rate control img->bot_MB = 1; – Encode one MB start_macroblock (Current. Mb. Addr+1, TRUE); rdopt = &rddata_bot_field_mb; // store data in bottom field MB encode_one_macroblock (); // code the MB as field MB Field. RDCost += rdopt->min_rdcost;
Main function code(12)- MBAFF • Decide between frame/field MB pair if ( ((input->Mb. Interlace == ADAPTIVE_CODING) && (Frame. RDCost < Field. RDCost)) || input->Mb. Interlace == FRAME_MB_PAIR_CODING ) { img->field_mode = 0; //Frame MB MBPair. Is. Field = 0; } else { img->field_mode = 1; //Field MB MBPair. Is. Field = 1; }
Main function code(13)- MBAFF if (recode_macroblock == FALSE) { } Current. Mb. Addr = Fmo. Get. Next. MBNr (Current. Mb. Addr); if (Current. Mb. Addr == -1) // end of slice end_of_slice = TRUE; Number. Of. Coded. MBs++; proceed 2 next. Macroblock (); write_one_macroblock (0); //wrt bot MB to bitstream terminate_macroblock (&end_of_slice, &recode_macroblock);
Main function code(14)- MBAFF else { img->current_mb_nr = Fmo. Get. Previous. MBNr(img->current_mb_nr); if(img->current_mb_nr == -1 ) error (errortext, 300); } //End of MBAFF mode
Main function code(15)End of encoding a Slice Group while (end_of_slice == FALSE) { -Encode by PAFF mode -Encode by MBAFF mode } terminate_slice ( (Number. Of. Coded. MBs+Total. Coded. MBs >= (int)img->Pic. Size. In. Mbs) ); return Number. Of. Coded. MBs;
H. 264 Code Tracing Deblock. Mb() No. 3 9762642 陳則伊
Introduction-caller and goal • “loop. Filter. c” • Caller: Deblock. Frame() • Goal: Deblocking filter for one MB – No filter beyond picture boundary – Compute strength values for one stripe in a MB – Filters luma/chroma block edge for frame or field coded pictures
Introduction-input and output • Input: – Image. Parameters *img – imgpel **img. Y – imgpel ***img. UV – int Mb. QAddr //index of MB in a frame • Output: – void
Local Variables 1) 2) 3) 4) 5) 6) 7) 8) 9) 10) 11) 12) int Edge. Condition; int dir, edge; byte Strength[16]; int mb_x, mb_y; int filter. Non 8 x 8 Luma. Edges. Flag[4] = {1, 1, 1, 1}; int filter. Left. Mb. Edge. Flag; int filter. Top. Mb. Edge. Flag; int field. Mode. Mb. Flag; int mvlimit = 4; int i, Strength. Sum; Macroblock *Mb. Q; int edge_cr;
Main function code(1) ① img->Deblock. Call = 1; ② get_mb_pos (Mb. QAddr, &mb_x, &mb_y, IS_LUMA); ③ filter. Left. Mb. Edge. Flag = (mb_x != 0); ④ filter. Top. Mb. Edge. Flag = (mb_y != 0); ⑤ Mb. Q = &(img->mb_data[Mb. QAddr]) ; // current Mb ⑥ filter. Non 8 x 8 Luma. Edges. Flag[1] = filter. Non 8 x 8 Luma. Edges. Flag[3] = !(Mb. Q->luma_transform_size_8 x 8_flag);
Main function code(2) ① if (img->Mbaff. Frame. Flag && mb_y == MB_BLOCK_SIZE && Mb. Q->mb_field) ② filter. Top. Mb. Edge. Flag = 0; ③ field. Mode. Mb. Flag = (img->structure!=FRAME) || (img->Mbaff. Frame. Flag && Mb. Q->mb_field); ④ if (field. Mode. Mb. Flag) ⑤ mvlimit = 2;
Main function code(3) ① if (Mb. Q->LFDisable. Idc==1) { //return, if filter is disabled ② img->Deblock. Call = 0; ③ return; ④ } ⑤ if (Mb. Q->LFDisable. Idc==2){ // don't filter at slice boundaries ⑥ filter. Left. Mb. Edge. Flag = Mb. Q->mb. Avail. A; ⑦ filter. Top. Mb. Edge. Flag = (img->Mbaff. Frame. Flag && !Mb. Q->mb_field && (Mb. QAddr & 0 x 01)) ? 1 : Mb. Q->mb. Avail. B; ⑧ } ⑨ img->current_mb_nr = Mb. QAddr; ⑩ Check. Availability. Of. Neighbors();
Main function code(4) ① for( dir = 0 ; dir < 2 ; dir++ ) // 0=vertical edges; 1=horizontal ② { ③ Edge. Condition = (dir && filter. Top. Mb. Edge. Flag) || (!dir && filter. Left. Mb. Edge. Flag); ④ for( edge=0; edge<4 ; edge++ ) // first 4 vertical strips of 16 pel ⑤ { // then 4 horizontal ⑥ if( edge || Edge. Condition ) ⑦ { ⑧ edge_cr = chroma_edge[dir][edge][img->yuv_format]; ⑨ Get. Strength(Strength, img, Mb. QAddr, dir, edge << 2, mvlimit); ⑩ Strength. Sum = Strength[0]; ……
Main function code(5) ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ① ② for (i = 0; i < MB_BLOCK_SIZE; i++) { if (Strength. Sum) break; Strength. Sum += Strength[i]; } if( Strength. Sum ) { // only if one of the 16 Strength bytes is != 0 if (filter. Non 8 x 8 Luma. Edges. Flag[edge]) Edge. Loop. Luma( img. Y, Strength, img, Mb. QAddr, Mb. Q->LFAlpha. C 0 Offset, Mb. Q->LFBeta. Offset, dir, edge << 2, img->width) ; if( (img. UV != NULL) && (edge_cr >= 0)) { Edge. Loop. Chroma( img. UV[0], Strength, img, Mb. QAddr, Mb. Q->LFAlpha. C 0 Offset, Mb. Q->LFBeta. Offset, dir, edge_cr, img->width_cr, 0) ; Edge. Loop. Chroma( img. UV[1], Strength, img, Mb. QAddr, Mb. Q->LFAlpha. C 0 Offset, Mb. Q->LFBeta. Offset, dir, edge_cr, img->width_cr, 1) ; } }
Main function code(6) ① ② ③ ④ if (dir && !edge && !Mb. Q->mb_field && mixed. Mode. Edge. Flag) { // extra horizontal edge between a frame macroblock pair and a field img->Deblock. Call = 2; Get. Strength(Strength, img, Mb. QAddr, dir, MB_BLOCK_SIZE, mvlimit); ……
Main function code(7) ① ② ③ ④ ⑤ if (filter. Non 8 x 8 Luma. Edges. Flag[edge]) Edge. Loop. Luma( img. Y, Strength, img, Mb. QAddr, Mb. Q->LFAlpha. C 0 Offset, Mb. Q->LFBeta. Offset, dir, 16, img->width) ; if( (img. UV != NULL) && (edge_cr >= 0)) { Edge. Loop. Chroma( img. UV[0], Strength, img, Mb. QAddr, Mb. Q->LFAlpha. C 0 Offset, Mb. Q->LFBeta. Offset, dir, MB_BLOCK_SIZE, img->width_cr, 0) ; Edge. Loop. Chroma( img. UV[1], Strength, img, Mb. QAddr, Mb. Q->LFAlpha. C 0 Offset, Mb. Q->LFBeta. Offset, dir, MB_BLOCK_SIZE, img->width_cr, 1) ; } img->Deblock. Call = 1; ⑥ ⑦ ⑧ } ⑨ } ⑩ } //end edge ① } //end loop dir ② img->Deblock. Call = 0;
- Slides: 32