?? skl_mpg4_rvop.cpp
字號:
Tmp[3][1] = SCALE_UP_MV(MV2[1][1]); Clip_Field(Tmp[0], Tmp[0]); // TODO: dunno if it's correct. Clip_Field(Tmp[1], Tmp[1]); Clip_Field(Tmp[2], Tmp[2]); Clip_Field(Tmp[3], Tmp[3]); if (!VOL->Quarter) { SKL_BYTE * Y = Y1; Predict_16x8 (Y, Y +Fwd_CoLoc, Tmp[0], Ops); Predict_16x8 (Y+BpS8, Y+BpS8 +Fwd_CoLoc, Tmp[0], Ops); Predict_16x8 (Y+16, Y+16 +Fwd_CoLoc, Tmp[1], Ops); Predict_16x8 (Y+16+BpS8,Y+16+BpS8+Fwd_CoLoc, Tmp[1], Ops); Y += 2*BpS8; Predict_16x8 (Y, Y +Fwd_CoLoc, Tmp[2], Ops); Predict_16x8 (Y+BpS8, Y+BpS8 +Fwd_CoLoc, Tmp[2], Ops); Predict_16x8 (Y+16, Y+16 +Fwd_CoLoc, Tmp[3], Ops); Predict_16x8 (Y+16+BpS8,Y+16+BpS8+Fwd_CoLoc, Tmp[3], Ops); } else { SKL_BYTE * Y = Y1; Predict_16x16_QP(Y, Y +Fwd_CoLoc, Tmp[0], Ops); Predict_16x16_QP(Y+16,Y+16+Fwd_CoLoc, Tmp[1], Ops); Y += 2*BpS8; Predict_16x16_QP(Y, Y +Fwd_CoLoc, Tmp[2], Ops); Predict_16x16_QP(Y+16,Y+16+Fwd_CoLoc, Tmp[3], Ops); } SKL_MV uv_MV; Derive_uv_MV_From_4MV(uv_MV, &Tmp[0], &Tmp[2]); const int Halves = (uv_MV[0]&1) | ((uv_MV[1]&1)<<1); const int Off = Fwd_CoLoc + (uv_MV[1]>>1)*BpS + (uv_MV[0]>>1); Ops->HP_16x8[Halves](U, U +Off, BpS); Ops->HP_16x8[Halves](U+BpS8, U+BpS8+Off, BpS); Ops->HP_16x8[Halves](V, V +Off, BpS); Ops->HP_16x8[Halves](V+BpS8, V+BpS8+Off, BpS);}#undef SCALE_UP_MV//////////////////////////////////////////////////////////static void Read_Reduced_P_VOP(SKL_FBB * const Bits, const SKL_MP4_I * const VOP){ SKL_ASSERT(VOP->Reduced_VOP>0); SKL_MB MB(VOP); SKL_INT16 Base[7*64+SKL_ALIGN]; SKL_INT16 * const In = (SKL_INT16*)SKL_ALIGN_PTR(Base, SKL_ALIGN); while(MB.y<VOP->MB_H) { MB.Init_Scanline(VOP, 0); const SKL_MV *Left_Predictor = MB.MVs - 1; while(MB.x<VOP->MB_W) { if (Bits->Get_Bits(1)) // not coded { SKL_ASSERT(!MB.MC_Sel); // no Reduced_VOP for GMC MB.MB_Type = SKL_MB_SKIPPED; MB.Predict_Reduced_With_0MV(); MB.Store_Zero_MV(); MB.Set_Not_Intra(); Left_Predictor = &MB.MVs[1]; // no post-filter for skipped macroblock } else { MB.Decode_Inter_Infos(Bits, Left_Predictor); SKL_ASSERT(MB.MC_Sel==0); // no reduced VOP for GMC if (MB.MB_Type >= SKL_MB_INTRA) { /* INTRA or INTRA_Q */ MB.Decode_Intra_Blocks(Bits, In, VOP); MB.Copy_16To8_Upsampled(In+1*64); MB.Store_Zero_MV(); Left_Predictor = &MB.MVs[1]; } else { MB.Set_Not_Intra(); if (MB.MB_Type == SKL_MB_INTER4V) { MB.Predict_Reduced_With_4MV(MB.MVs, MB.MVs2); Left_Predictor = &MB.MVs[1]; } else /* INTER or INTER_Q */ { if (MB.Field_Pred) { // Impl: we don't multiply the final field // vectors by 2 (cf. Store_16x8_MV()) MB.Predict_Reduced_Fields(MB.MVs, MB.Field_Dir); MB.Store_16x8_MV(&MB.MVs2[0], &MB.MVs[0]); // field MV mode Left_Predictor = &MB.MVs2[1]; // wow! } else { MB.Predict_Reduced_With_1MV(MB.MVs[0]); MB.Store_16x16_MV(); // 16x16 mode Left_Predictor = &MB.MVs[1]; } } MB.Decode_Inter_Blocks(Bits, In, VOP); MB.Add_16To8_Upsampled(In + 1*64); } Post_Filter(&MB); } MB.Store_Map_Infos(); MB.Expand_Reduced(); if (!MB.Resync || !MB.Resync_Marker(Bits)) MB.Next_Reduced(); if (VOP->Debug_Level==5) { if (MB.MB_Type==SKL_MB_SKIPPED) printf( "s" ); else if (MB.Field_Pred==1) printf( "=" ); else if (MB.MB_Type==SKL_MB_INTER4V) printf( "4" ); else printf( "%c", ".-="[1+MB.Field_DCT] ); if (MB.x==VOP->MB_W) printf( "\n" ); } } if (VOP->Debug_Level==2) VOP->Dump_Line(0, &MB); if (MB.y>0 && VOP->Slicer) VOP->Slicer(VOP->Cur, (MB.y-2)*16, 32, VOP->Slicer_Data); MB.y += 2; } if (VOP->Debug_Level==1) VOP->Dump_MVs(VOP->Cur, 2); if (MB.y>0 && VOP->Slicer) VOP->Slicer(VOP->Cur, (MB.y-2)*16, 32, VOP->Slicer_Data);}//////////////////////////////////////////////////////////// entry pointvoid SKL_MP4_I::Read_Reduced_VOP(SKL_FBB * const Bits) const{ SKL_ASSERT(Reduced_VOP==1 && Coding!=B_VOP && Coding!=S_VOP); if (Coding==I_VOP) Read_Reduced_I_VOP(Bits, this); else /* P/S-VOP */ Read_Reduced_P_VOP(Bits, this);}////////////////////////////////////////////////////////////// Encoding////////////////////////////////////////////////////////////void SKL_MB_ENC::Copy_8To16_Downsampled(SKL_INT16 Out[6*64]) const{ if (Field_DCT<=0) { VOL->MB_Ops.Filter_18x18_To_8x8(Out+0*64, Y1, BpS); VOL->MB_Ops.Filter_18x18_To_8x8(Out+1*64, Y1+16, BpS); VOL->MB_Ops.Filter_18x18_To_8x8(Out+2*64, Y1+16*BpS, BpS); VOL->MB_Ops.Filter_18x18_To_8x8(Out+3*64, Y1+16*BpS+16, BpS); } else { VOL->MB_Ops.Filter_18x18_To_8x8(Out+0*64, Y1, 2*BpS); VOL->MB_Ops.Filter_18x18_To_8x8(Out+1*64, Y1+16, 2*BpS); VOL->MB_Ops.Filter_18x18_To_8x8(Out+2*64, Y1+BpS, 2*BpS); VOL->MB_Ops.Filter_18x18_To_8x8(Out+3*64, Y1+BpS+16, 2*BpS); } VOL->MB_Ops.Filter_18x18_To_8x8(Out+4*64, U, BpS); VOL->MB_Ops.Filter_18x18_To_8x8(Out+5*64, V, BpS);}void SKL_MB_ENC::Diff_8To16_Downsampled(SKL_INT16 Out[6*64]) const{ if (Field_DCT<=0) { VOL->MB_Ops.Filter_Diff_18x18_To_8x8(Out+0*64, Y1, BpS); VOL->MB_Ops.Filter_Diff_18x18_To_8x8(Out+1*64, Y1+16, BpS); VOL->MB_Ops.Filter_Diff_18x18_To_8x8(Out+2*64, Y1+16*BpS, BpS); VOL->MB_Ops.Filter_Diff_18x18_To_8x8(Out+3*64, Y1+16*BpS+16, BpS); } else { VOL->MB_Ops.Filter_Diff_18x18_To_8x8(Out+0*64, Y1, 2*BpS); VOL->MB_Ops.Filter_Diff_18x18_To_8x8(Out+1*64, Y1+16, 2*BpS); VOL->MB_Ops.Filter_Diff_18x18_To_8x8(Out+2*64, Y1+BpS, 2*BpS); VOL->MB_Ops.Filter_Diff_18x18_To_8x8(Out+3*64, Y1+BpS+16, 2*BpS); } VOL->MB_Ops.Filter_Diff_18x18_To_8x8( Out+4*64, U, BpS); VOL->MB_Ops.Filter_Diff_18x18_To_8x8( Out+5*64, V, BpS);}////////////////////////////////////////////////////////// void SKL_MB_ENC::Decimate_Reduced_Intra(SKL_INT16 Out[12*64]) const{ Copy_8To16_Downsampled(Out+6*64); // import SKL_INT16 *C = Out; // Decimate const SKL_MP4_ENC_I * const Vol = (const SKL_MP4_ENC_I *)VOL; for(int blk=0; blk<6; ++blk) { const int DC_Q = SKL_MP4_I::DC_Scales[(blk<4)][Quant-1]; Vol->Decimate_Intra(C, C+6*64, Quant, DC_Q); C += 64; } Copy_16To8_Upsampled(Out+6*64); // transfer back decimated data}//////////////////////////////////////////////////////////void SKL_MP4_ENC_I::Write_Reduced_I_VOP(SKL_FBB * const Bits){ SKL_INT16 Base[12*64+SKL_ALIGN]; SKL_INT16 * const In = (SKL_INT16*)SKL_ALIGN_PTR(Base, SKL_ALIGN); SKL_MB_ENC MB(this); while(MB.y<MB_H) { MB.Init_Scanline(this, 0); while(MB.x<MB_W) { MB.MB_Type = SKL_MB_INTRA; MB.Set_Final_Params(); SKL_ASSERT(MB.MB_Type == SKL_MB_INTRA); MB.Decimate_Reduced_Intra(In); MB.Encode_Intra(Bits, In, 1); Post_Filter(&MB); MB.Expand_Reduced(); MB.Next_Reduced(); } if (Debug_Level==2) Dump_Line(0, &MB); if (MB.y>0 && Slicer) Slicer(Cur, (MB.y-2)*16, 32, Slicer_Data); MB.y+=2; } if (MB.y>0 && Slicer) Slicer(Cur, (MB.y-2)*16, 32, Slicer_Data); Texture_Bits = MB.Get_Texture_Bits(); MV_Bits = MB.Get_MV_Bits();}///////////////////////////////////////////////////////////*#define SCALE_DOWN(V) \ (V)[0][0] = ( (V)[0][0] + (V)[2][0] + (V)[2*MV_Stride][0] + (V)[2*MV_Stride+2][0] ) >> 3; \ (V)[0][1] = ( (V)[0][1] + (V)[2][1] + (V)[2*MV_Stride][1] + (V)[2*MV_Stride+2][1] ) >> 3*/#define SCALE_DOWN(V) (V)[0][0] /= 2; (V)[0][1] /= 2static inline int Find_Last(const SKL_INT16 C[6*64], const int *Zigzag, int i){ while(i>=0) if (C[Zigzag[i]]) return i; else i--; return -1;}void SKL_MB_ENC::Decimate_Reduced_Inter(SKL_INT16 Out[12*64]){ if (MB_Type==SKL_MB_SKIPPED) { Predict_Reduced_With_0MV(); Store_Zero_MV(); return; } // Fwd predict int Skippable = (dQuant==0) && SKL_IS_ZERO_MV(MVs[0]); Copy_8To16_Downsampled(Out+6*64); // save original data if (Field_Pred) { // form predictions Predict_Reduced_Fields(MVs, Field_Dir); Store_16x8_MV(&MVs2[0], &MVs[0]); SKL_COPY_MV(MVs[1], MVs2[0]); // update left predictor if (Skippable) Skippable &= SKL_IS_ZERO_MV(MVs2[0]); } else { if (MB_Type!=SKL_MB_INTER4V) { Predict_Reduced_With_1MV(MVs[0]); Store_16x16_MV(); } else { Predict_Reduced_With_4MV(&MVs[0], &MVs2[0]); if (Skippable) { Skippable &= SKL_IS_ZERO_MV(MVs [1]); Skippable &= SKL_IS_ZERO_MV(MVs2[0]); Skippable &= SKL_IS_ZERO_MV(MVs2[1]); } } } Diff_8To16_Downsampled(Out+6*64); // diff original/predicted data SKL_INT16 *C = Out; // Decimate and set Cbp Cbp = 0x00; const SKL_MP4_ENC_I * const Vol = (const SKL_MP4_ENC_I *)VOL; for(int blk=0; blk<6; ++blk) { const int SAV = Vol->Decimate_Inter(C, C+6*64,Quant); if (SAV>0) { Last[blk] = Find_Last(C, SKL_MP4_I::Scan_Order[0], 63); SKL_ASSERT(Last[blk]>=0); Cbp |= 1<<(5-blk); } else Last[blk] = -1; C += 64; } if (Skippable && Cbp==0) MB_Type = SKL_MB_SKIPPED; // won't be coded (don't transfer back data) else Add_16To8_Upsampled(Out+6*64); // transfer back decimated delta data}void SKL_MP4_ENC_I::Write_Reduced_P_VOP(SKL_FBB * const Bits){ SKL_INT16 Base[12*64+SKL_ALIGN]; SKL_INT16 * const In = (SKL_INT16*)SKL_ALIGN_PTR(Base, SKL_ALIGN); SKL_MB_ENC MB(this); while(MB.y<MB_H) { MB.Init_Scanline(this, 0); while(MB.x<MB_W) { MB.Set_Type(); SKL_ASSERT(MB.MB_Type!=SKL_MB_INTER4V); if (MB.MB_Type!=SKL_MB_SKIPPED) { SCALE_DOWN(MB.MVs); MB.Set_Final_Params(); } if (MB.MB_Type==SKL_MB_INTRA) MB.Decimate_Reduced_Intra(In); else MB.Decimate_Reduced_Inter(In); if (MB.MB_Type==SKL_MB_SKIPPED) { Bits->Put_Bits( 1, 1 ); // not_coded MB.Set_Not_Intra(); } else { Bits->Put_Bits( 0, 1 ); // coded if (MB.MB_Type>=SKL_MB_INTRA) MB.Encode_Intra(Bits, In, 0); else MB.Encode_Inter(Bits, In, Fwd_Code); Post_Filter(&MB); } MB.Store_Map_Infos(); MB.Expand_Reduced(); MB.Next_Reduced(); } if (Debug_Level==2) Dump_Line(0, &MB); if (MB.y>0 && Slicer) Slicer(Cur, (MB.y-2)*16, 32, Slicer_Data); MB.y += 2; } if (MB.y>0 && Slicer) Slicer(Cur, (MB.y-2)*16, 32, Slicer_Data); Texture_Bits = MB.Get_Texture_Bits(); MV_Bits = MB.Get_MV_Bits(); if (Debug_Level==1) Dump_MVs(Cur, 2); // will trash the encoded frame}#undef SCALE_DOWN//////////////////////////////////////////////////////////
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -