亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
查看: 853 | 回復(fù): 0
打印 上一主題 下一主題

xvid編碼 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2011-12-20 09:44 |只看該作者 |倒序?yàn)g覽

xvid有兩種編碼方式:single pass和twopass 
single pass模式編碼簡(jiǎn)單,速度也快,但最終效果不如twopass。 
twopass就是視頻壓制需要經(jīng)過(guò)兩次編碼,分別為twopass-1st pass(簡(jiǎn)稱1pass)和twopass-2nd pass(簡(jiǎn)稱2pass) 
1pass時(shí),編碼器會(huì)用最高質(zhì)量編碼采集可供第2次運(yùn)算參考的畫面信息,而在2 pass時(shí)。編碼器會(huì)根據(jù)第一次壓縮獲得的信息和用戶指定的文件大小,自動(dòng)分配比特率,使需要高流量的運(yùn)動(dòng)畫面分配到更多的空間,更高的比特率來(lái)保證畫面質(zhì)量。相對(duì)的,對(duì)于那些不包含太多運(yùn)動(dòng)信息的靜態(tài)畫面則用較低的比特率。追求畫質(zhì)的朋友當(dāng)然會(huì)選擇這種方式,但運(yùn)算比single pass更費(fèi)時(shí)。 

接下來(lái)介紹一些基本概念: 
Q值——量化值,它被用來(lái)描述1幀的質(zhì)量,每幀都有一個(gè)Q值,取值范圍在1-31之間。Q值越小,畫質(zhì)越好,比特率越大 
I-frame——關(guān)鍵幀,常被縮寫為IF。關(guān)鍵幀是構(gòu)成一個(gè)幀組的第一幀。IF保留了一個(gè)場(chǎng)景的所有信息 
P-frame——未來(lái)單項(xiàng)預(yù)測(cè)幀,縮寫為PF,只儲(chǔ)存與之前一個(gè)已解壓畫面的差值 
B-frame——雙向預(yù)測(cè)幀,縮寫為BF,除了參考之前解壓的畫面以外,也會(huì)參考后一幀的畫面信息 

 

編碼流程: 

 

各變量的設(shè)置:創(chuàng)建xvid_enc_frame_t和xvid_enc_stats_t,分別用于傳入?yún)?shù)和統(tǒng)計(jì)編碼結(jié)果。 

具體過(guò)程: 

設(shè)置傳入圖像數(shù)據(jù)和圖像色彩空間 

設(shè)置傳出的碼流 

設(shè)置vol的標(biāo)志 

設(shè)置幀的編碼類型 

設(shè)置量化因子 

設(shè)置運(yùn)動(dòng)估計(jì)算法集合 

設(shè)置vop的標(biāo)志 

 

編碼器提供的函數(shù) 

1, xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL); 

含義:根據(jù)cpu的特性使用相應(yīng)匯編優(yōu)化的函數(shù) 

 

2, xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL); 

含義:初始化編碼器。 

具體過(guò)程: 

創(chuàng)建編碼器句柄,并根據(jù)傳入的參數(shù)設(shè)置各變量的值,并且分配要使用的內(nèi)存,用于存放重建幀,參考幀(1/2像素精度)。以及各種臨時(shí)變量。并且做好碼率控制的初始化。 

 

3, xvid_encore(enc_handle, XVID_ENC_ENCODE, &xvid_enc_frame, &xvid_enc_stats); 

目的:編碼一幀 

具體過(guò)程: 

初始化寫碼流。 

如果有必要,轉(zhuǎn)換色彩空間,并且把原始圖像拷貝到有邊框的圖像空間,但是沒(méi)有擴(kuò)展邊框。 

將重建幀交換成參考幀 

從幀隊(duì)列中獲取當(dāng)前幀 

設(shè)置Encoder結(jié)構(gòu)體的current結(jié)構(gòu)體的vol_flags,vop_flags,motion_flags,fcode,bcode和quant字段。 

調(diào)用call_plugins,在里面調(diào)用rc_single_before做碼率控制的初始化,以及對(duì)current結(jié)構(gòu)體的其他變量進(jìn)一步設(shè)置 

通過(guò)幀號(hào)或者M(jìn)Eanalysis函數(shù)分析來(lái)確定編碼類型,并且根據(jù)用戶的設(shè)置作修正。 

MEanalysis的原理是,如果某個(gè)宏塊的殘差的sad大于該宏塊的平均值的偏離,那么使用intra方式,否則使用inter方式,然后對(duì)這些宏塊進(jìn)行統(tǒng)計(jì),得到整幀的編碼方式。 

 

如果編碼類型是I_VOP 

設(shè)置Encoder->mbParam->vol_flags 

設(shè)置Encoder->mbParam.par 

根據(jù)vol_flags設(shè)置vop_flags 

調(diào)用FrameCodeI以I幀的方式編碼 

調(diào)用call_plugins,在里面調(diào)用rc_single_after,進(jìn)行碼率控制。 

 

如果編碼類型是P_VOP 

用mbParam.vol_flags固定住pEnc->current->vol_flags 

調(diào)用FrameCodeP以P幀的方式編碼 

調(diào)用call_plugins,在里面調(diào)用rc_single_after,進(jìn)行碼率控制。 

}// xvid_encore 

 

4, static int FrameCodeI(Encoder * pEnc, Bitstream * bs) 

目的:將一幀圖像編碼成一個(gè)I幀 

具體過(guò)程: 

以XVID_PLG_FRAME參數(shù)調(diào)用call_plugins,該函數(shù)目前的作用是設(shè)置dquant,可以在該函數(shù)中設(shè)置最好質(zhì)量。 

調(diào)用SetMacroblockQuants,為每個(gè)宏塊設(shè)置量化因子,所以也可以在這里設(shè)置最好質(zhì)量 

調(diào)用BitstreamWriteVolHeader,寫vol 

調(diào)用set_timecodes,設(shè)置時(shí)間編碼。 

調(diào)用BitstreamPad,填充bit至字節(jié)對(duì)齊 

調(diào)用BitstreamWriteVopHeader,填寫vop頭 

 

依次讀取每一個(gè)宏塊,進(jìn)行編碼 

調(diào)用CodeIntraMB設(shè)置編碼模式為intra,將所有和運(yùn)動(dòng)有關(guān)的變量設(shè)為0 

調(diào)用MBTransQuantIntra進(jìn)行變換編碼 

調(diào)用MBTrans8to16將像素的表示方法從8bit擴(kuò)大到16bit 

調(diào)用MBfDCT對(duì)像素進(jìn)行變換編碼 

調(diào)用MBQuantIntra對(duì)dct系數(shù)進(jìn)行intra方式的量化 

調(diào)用MBDeQuantIntra對(duì)dct系數(shù)進(jìn)行intra方式的反量化 

調(diào)用MBiDCT將恢復(fù)的dct系數(shù)進(jìn)行反變換 

調(diào)用MBTrans16to8將恢復(fù)的16bit像素飽和到8bit,組成重建宏塊 

}//MBTransQuantIntra 

 

調(diào)用MBPrediction作acdc預(yù)測(cè) 

調(diào)用get_dc_scaler函數(shù)得到量化系數(shù) 

調(diào)用predict_acdc得到預(yù)測(cè)方向以及在該預(yù)測(cè)方向上的和當(dāng)前塊的同一量化水平的預(yù)測(cè)值 

調(diào)用calc_acdc_bits以確定是只使用DC預(yù)測(cè),還是DCAC預(yù)測(cè)。原理是分別作DC預(yù)測(cè)和DCAC預(yù)測(cè),分別計(jì)算在這2種情況下需要的碼流長(zhǎng)度,以確定哪種方式更節(jié)約碼流。 

調(diào)用CodeCoeffIntra_CalcBits,用于確定各種方式下的碼流長(zhǎng)度 

根據(jù)預(yù)測(cè)模式的不同,恢復(fù)成相應(yīng)的系數(shù) 

最后計(jì)算該宏塊的cbp 

}//MBPrediction 

 

調(diào)用MBCoding將宏塊編制成碼流 

調(diào)用CodeBlockIntra將intra宏塊編制成碼流 

編碼mcbpc 

編碼ac預(yù)測(cè)標(biāo)記 

編碼cbpy 

對(duì)于6個(gè)塊里的每個(gè)塊 

首先編碼DC系數(shù) 

調(diào)用CodeCoeffIntra對(duì)剩下的63個(gè)系數(shù)進(jìn)行編碼 

}//CodeBlockIntra 

}//MBCoding 

 

}//依次讀取每一個(gè)宏塊,進(jìn)行編碼 

 

填充bit,直到字節(jié)對(duì)齊 

 

 

5, static int FrameCodeP(Encoder * pEnc, Bitstream * bs) 

含義:將一幀圖片編碼成P幀 

具體過(guò)程: 

如果參考幀還沒(méi)有設(shè)置邊框,那么就調(diào)用image_setedges設(shè)置邊框 

如果需要半像素運(yùn)動(dòng)估計(jì),那么就調(diào)用image_interpolate進(jìn)行插值 

將一幀填充邊框后的參考幀,分成8*8的小塊,對(duì)于每個(gè)小塊進(jìn)行插值,如下: 

調(diào)用interpolate8x8_halfpel_h進(jìn)行水平插值 

調(diào)用interpolate8x8_halfpel_v進(jìn)行垂直插值 

調(diào)用interpolate8x8_halfpel_hv進(jìn)行對(duì)角線插值 

用參數(shù)XVID_PLG_FRAME調(diào)用call_plugins,該函數(shù)目前的作用是設(shè)置dquant,可以在該函數(shù)中設(shè)置最好質(zhì)量。 

調(diào)用SetMacroblockQuants,為每個(gè)宏塊設(shè)置量化因子,所以也可以在這里設(shè)置最好質(zhì)量 

調(diào)用MotionEstimation做運(yùn)動(dòng)估計(jì) 

使用MotionFlags變量保存要使用的運(yùn)動(dòng)算法集合 

使用skip_thresh保存要達(dá)到skip模式的閥值 

使用Data保存運(yùn)動(dòng)估計(jì)要用到的相應(yīng)變量 

對(duì)于每個(gè)宏塊,依次執(zhí)行如下操作 

調(diào)用sad16v計(jì)算本宏塊與參考幀對(duì)應(yīng)位置宏塊的亮度的殘差,將其保存在pMB->sad16中,并按照4個(gè)塊的方式分別存放pMB->sad8[0-3]中 

用sad00記錄最大亮度塊殘差的4倍 

如果還需要考慮色差塊的因素 

調(diào)用sad8兩次,分別計(jì)算u分量和v分量的殘差,都加入pMB->sad16中,并且也加入sad00中 

如果該宏塊的量化差值為0,并且sad00又沒(méi)有超過(guò)skip模式的閥值 

如果已經(jīng)考慮了色差因素,或者使用xvid_me_SkipDecisionP確認(rèn)符合skip模式。 

調(diào)用ZeroMacroblockP將其編碼為skip模式,并置標(biāo)記pMB->mode = MODE_NOT_CODED 

根據(jù)采用的運(yùn)動(dòng)估計(jì)算法不同,做相應(yīng)的設(shè)置 

調(diào)用SearchP做該宏塊的運(yùn)動(dòng)估計(jì) 

確定是否使用inter4v模式,并記錄之 

調(diào)用get_range確定運(yùn)動(dòng)搜索的范圍,并記錄在Data中 

調(diào)用get_pmvdata2,以獲得左,上,右上的運(yùn)動(dòng)向量,以及它們對(duì)應(yīng)的sad,存入pmv[1-3]和Data->temp[1-3]。然后計(jì)算它們的中值,并且存放于pmv[0],并且把最小的sad存放于Data->temp[0] 

設(shè)置Data的當(dāng)前宏塊的yuv字段。設(shè)置Data->RefP[0-5]為參考幀的同一宏塊的整像素y,水平半象素y,垂直半象素y,對(duì)角線y,u,v。 

設(shè)置Data->lambda16和Data->lambda8,其含義可能是運(yùn)動(dòng)向量對(duì)帶寬的占用折合到sad的值 

設(shè)置qpel和方向 

如果采用qpel,調(diào)用get_qpmv2計(jì)算用qple方式下的估計(jì)中值,存入ata->predMV;否則,Data->predMV為0。 

調(diào)用d_mv_bits計(jì)算mv需要的編碼bit,用于修正pMB->sad16和pMB->sad8[0],并將Data->iMinSAD[0-4]設(shè)置為pMB->sad16和pMB->sad8[0-3],也就是0向量對(duì)應(yīng)的各SAD。 

如果不采用率失真決策模型,并且不是當(dāng)前幀的第一宏塊,那么使用一種方法設(shè)置閥值threshA,否則閥值threshA為512。 

 

調(diào)用PreparePredictionsP,對(duì)pmv作進(jìn)一步的設(shè)置,做運(yùn)算前的準(zhǔn)備。 

設(shè)置pmv[0]為0向量 

設(shè)置pmv[1]為中值向量的偶數(shù)值 

設(shè)置pmv[2]為參考幀相同位置宏塊的第0塊運(yùn)動(dòng)向量的偶數(shù)值 

如果該宏塊有左邊宏塊,設(shè)置pmv[3]為左邊宏塊的第1塊的運(yùn)動(dòng)向量的偶數(shù)值,否則為0 

如果該宏塊有上面宏塊,設(shè)置pmv[4]為上面宏塊的第2塊的運(yùn)動(dòng)向量的偶數(shù)值,否則為0 

如果該宏塊有右上宏塊,設(shè)置pmv[5]為右上宏塊的第2塊的運(yùn)動(dòng)向量的偶數(shù)值,否則為0 

如果該宏塊有右下宏塊,設(shè)置pmv[6]為參考幀的相同宏塊的右下宏塊的第0塊的運(yùn)動(dòng)向量的偶數(shù)值,否則為0。 

}//PreparePredictionsP 

 

如果使用inter4v,設(shè)置CheckCandidate為CheckCandidate16,否則設(shè)置為CheckCandidate16no4v 

 

逐一檢查mpv[1-6]這六個(gè)最可能運(yùn)動(dòng)向量,如果發(fā)現(xiàn)他們與以前的運(yùn)動(dòng)不同,就調(diào)用CheckCandidate做運(yùn)動(dòng)估計(jì),過(guò)程如下: 

檢查要做運(yùn)動(dòng)估計(jì)的運(yùn)動(dòng)向量是否越界 

通過(guò)該運(yùn)動(dòng)向量獲得所指向數(shù)據(jù)塊的指針 

調(diào)用sad16v,記錄下4個(gè)8*8塊的SAD值,存入data->temp[0-3]中,并將他們的和存入臨時(shí)變量sad中。 

對(duì)sad和data->temp[0]做基于運(yùn)動(dòng)向量的修正。 

如果要考慮色差因素,調(diào)用xvid_me_ChromaSAD計(jì)算額外的SAD,累加至sad中。 

如果sad小于data->iMinSAD[0],那么設(shè)置data->iMinSAD[0],data->currentMV[0],和data->dir。注意,此時(shí)的data->dir記錄的不是鉆石搜索的方向,而是當(dāng)前向量是pmv數(shù)組的第幾個(gè)元素。 

逐一檢查data->temp[0-3],如果他們小于data->iMinSAD[1-4],那么修改data->iMinSAD[1-4]和data->currentMV[1-4] 

}//CheckCandidate 

 

如果當(dāng)前最優(yōu)運(yùn)動(dòng)向量,即Data->iMinSAD[0],小于threshA?或者當(dāng)前最優(yōu)運(yùn)動(dòng)向量等于參考幀相同位置宏塊的運(yùn)動(dòng)向量,并且對(duì)應(yīng)的SAD值又比他的小? 

就不再做inter4v的搜索 

否則,就做inter4v的搜索 

使用make_mask逐一檢查存放于pmv的所有運(yùn)動(dòng)向量,察看是否位于欲搜索的鉆石形的頂點(diǎn)。如果是,則在mask變量中標(biāo)記之。 

根據(jù)MotionFlags確定使用的搜索函數(shù),根據(jù)當(dāng)前設(shè)置,MainSearchPtr = xvid_me_AdvDiamondSearch 

調(diào)用xvid_me_AdvDiamondSearch進(jìn)行搜索,過(guò)程如下: 

bDirection既表明了上次嘗試的方向,又表明本次可以嘗試的方向 

x,y為鉆石搜索的位置的中心點(diǎn)坐標(biāo) 

for(;;) 

如果可以嘗試左邊,那么調(diào)用CheckCandidate嘗試左邊 

如果可以嘗試右邊,那么調(diào)用CheckCandidate嘗試右邊 

如果可以嘗試上邊,那么調(diào)用CheckCandidate嘗試上邊 

如果可以嘗試下邊,那么調(diào)用CheckCandidate嘗試下邊 

如果有更好的方向 

bDirection = 更好的方向 

如果更好的方向是左右方向,那么測(cè)試該位置的上下方向 

否則,那么測(cè)試該位置的左右方向 

如果這次又找到了更好的方向 

將更好的方向累加到bDirection 

將更好的位置存入x,y 

否則 

根據(jù)去搜索臨近未搜索的點(diǎn),具體規(guī)則如下: 

如果bDirection = = 2,表明搜索方向是趨向右邊的,那么搜索當(dāng)前中心點(diǎn)的右上點(diǎn)和右下點(diǎn)。 

如果bDirection = = 1,表明搜索方向是趨向左邊的,那么搜索當(dāng)前中心點(diǎn)的左上點(diǎn)和左下點(diǎn)。 

如果bDirection = = 2+4,表明搜索方向是趨向右上的,那么再搜索當(dāng)前中心點(diǎn)的左上點(diǎn),右上點(diǎn)和右下點(diǎn)。 

如果bDirection = = 4,表明搜索方向是趨向上邊的,那么搜索當(dāng)前中心點(diǎn)的左上點(diǎn)和右上點(diǎn)。 

如果bDirection = = 8,表明搜索方向是趨向下邊的,那么搜索當(dāng)前中心點(diǎn)的左下點(diǎn)和右下點(diǎn)。 

如果bDirection = = 1+4,表明搜索方向是趨向左上的,那么再搜索當(dāng)前中心點(diǎn)的左下點(diǎn),左上點(diǎn)和右上點(diǎn)。 

如果bDirection = = 2+8,表明搜索方向是趨向右下的,那么再搜索當(dāng)前中心點(diǎn)的左下點(diǎn),左上點(diǎn)和右上點(diǎn)。 

如果bDirection = = 1+8,表明搜索方向是趨向左下的,那么再搜索當(dāng)前中心點(diǎn)的左上點(diǎn),左下點(diǎn)和右下點(diǎn)。 

否則的話,則認(rèn)為本輪搜索沒(méi)有找到更好的點(diǎn),那么再搜索當(dāng)前中心點(diǎn)的左上點(diǎn),左下點(diǎn),右上點(diǎn),右下點(diǎn)。 

如果沒(méi)有找到更好的方向,從函數(shù)中返回 

更新bDirection為更好的方向 

更新x,y為更好的位置 

}//for(;;) 

 

}//xvid_me_AdvDiamondSearch 

 

如果運(yùn)動(dòng)估計(jì)算法使用了XVID_ME_EXTSEARCH16,那么 

設(shè)置startMV = Data->predMV 

設(shè)置backupMV為當(dāng)前最佳運(yùn)動(dòng)向量 

如果startMV和backupMV不相等 

調(diào)用CheckCandidate計(jì)算位置為startMV的SAD 

調(diào)用xvid_me_DiamondSearch做以startMV為起點(diǎn)的搜索,過(guò)程如下: 

for(;;) 

如果可以嘗試左邊,那么調(diào)用CheckCandidate嘗試左邊 

如果可以嘗試右邊,那么調(diào)用CheckCandidate嘗試右邊 

如果可以嘗試上邊,那么調(diào)用CheckCandidate嘗試上邊 

如果可以嘗試下邊,那么調(diào)用CheckCandidate嘗試下邊 

如果沒(méi)有更好的方向,退出 

bDirection = 更好的方向 

x,y = 更好的位置 

如果更好的方向是左右方向,那么測(cè)試該位置的上下方向 

否則,那么測(cè)試該位置的左右方向 

如果這次又找到了更好的方向 

bDirection += 更好的方向 

x,y = 更好的位置 

}//xvid_me_DiamondSearch 

 

將這次搜索結(jié)果和上次搜索結(jié)果比較,記錄最佳的SAD和位置。 

}//如果startMV和backupMV不相等 

 

設(shè)置startMV = {1,1} 

設(shè)置backupMV為當(dāng)前最佳運(yùn)動(dòng)向量 

如果startMV和backupMV不相等 

調(diào)用CheckCandidate計(jì)算位置為startMV的SAD 

調(diào)用xvid_me_DiamondSearch做以startMV為起點(diǎn)的搜索,過(guò)程如下: 

將這次搜索結(jié)果和上次搜索結(jié)果比較,記錄最佳的SAD和位置。 

}//如果運(yùn)動(dòng)估計(jì)算法使用了XVID_ME_EXTSEARCH16 

}//否則,就做inter4v的搜索 

 

如果沒(méi)有采用1/4像素運(yùn)動(dòng)估計(jì)算法 

如果采用了XVID_ME_HALFPELREFINE16算法 

調(diào)用xvid_me_SubpelRefine 

按順時(shí)針?lè)较?次調(diào)用CheckCandidate16,得到最好的1/2像素位置 

否則 

略 

 

如果當(dāng)前SAD足夠小,那么inter4v = 0 

如果采用inter4v 

4次調(diào)用Search8來(lái)搜索4個(gè)8*8塊的最佳運(yùn)動(dòng)向量,每一次搜索的規(guī)則如下: 

如果采用1/4像素運(yùn)動(dòng)估計(jì),略。否則 

調(diào)用get_pmv2取得本塊的中值 

計(jì)算第一塊以外快的d_mv_bits 

用Data->lambda8修正該塊當(dāng)前的SAD,但是第0塊是不用修正的。 

如果使用了XVID_ME_EXTSEARCH8 | XVID_ME_HALFPELREFINE8 | XVID_ME_QUARTERPELREFINE8,那么 

Data->RefP[0-3] = 參考幀的整像素,水平半象素,垂直半象素,對(duì)角線半象素的對(duì)應(yīng)宏塊的對(duì)應(yīng)塊的起始地址。 

Data->Cur = 當(dāng)前幀的當(dāng)前宏塊的當(dāng)前塊的起始地址 

利用get_range得到運(yùn)動(dòng)搜索的范圍 

根據(jù)MotionFlags的指示,設(shè)定運(yùn)動(dòng)估計(jì)MainSearchPtr的算法,當(dāng)前設(shè)置為MainSearchPtr = xvid_me_AdvDiamondSearch。 

調(diào)用xvid_me_AdvDiamondSearch做運(yùn)動(dòng)估計(jì),其中做SAD的函數(shù)是CheckCandidate8,該函數(shù)類似于CheckCandidate16 

如果不采用1/4像素運(yùn)動(dòng)估計(jì),并且又采用了XVID_ME_HALFPELREFINE8,那么調(diào)用xvid_me_SubpelRefine 

按順時(shí)針?lè)较?次調(diào)用CheckCandidate8,得到最好的1/2像素位置 

如果采用了1/4像素運(yùn)動(dòng)估計(jì),略 

}// XVID_ME_EXTSEARCH8 | XVID_ME_HALFPELREFINE8 | XVID_ME_QUARTERPELREFINE8 

 

如果采用1/4運(yùn)動(dòng)估計(jì) 

略 

否則 

記錄pMB->pmvs[block] = 當(dāng)前找到的最佳位置與預(yù)測(cè)位置的差值 

 

將這次的搜索存入相應(yīng)OldData的字段,以及pMB的相應(yīng)字段 

}// Search8 

如果考慮色差的因素,并且又不考慮率失真算法 

根據(jù)是否采用1/4像素運(yùn)動(dòng)估計(jì)算出色差的運(yùn)動(dòng)向量 

計(jì)算u,v的SAD,將其作為Data->iMinSAD[1]的修正 

} //如果采用inter4v 

否則,Data->iMinSAD[1]為足夠大的值 

}//SearchP 

 

調(diào)用ModeDecision_SAD確定該宏塊的類型 

判斷該宏塊要采取的編碼方式,MODE_INTER,MODE_INTER4V,MODE_NOT_CODED,MODE_INTRA 

調(diào)用motionStatsPVOP做一些統(tǒng)計(jì)工作 

具體過(guò)程略 

}//對(duì)于每個(gè)宏塊,依次執(zhí)行如下操作 

做一些最后的設(shè)置 

}//MotionEstimation 

 

調(diào)用set_timecodes設(shè)置時(shí)間戳 

調(diào)用BitstreamWriteVopHeader寫VOP頭 

具體過(guò)程略 

 

對(duì)于每一個(gè)宏塊,依次執(zhí)行如下操作 

如果該宏塊的編碼模式是MODE_INTRA或者M(jìn)ODE_INTRA_Q 

調(diào)用CodeIntraMB設(shè)置編碼模式為intra,將所有和運(yùn)動(dòng)有關(guān)的變量設(shè)為0 

調(diào)用MBTransQuantIntra進(jìn)行變換編碼 

調(diào)用MBCoding將該宏塊編制成碼流 

Continue 

 

調(diào)用MBMotionCompensation做運(yùn)動(dòng)補(bǔ)償 

如果編碼模式是MODE_NOT_CODED 

用參考幀的相應(yīng)宏塊替代當(dāng)前幀的當(dāng)前宏塊 

Return 

 

如果編碼模式是MODE_NOT_CODED或者M(jìn)ODE_INTER或者M(jìn)ODE_INTER_Q 

如果mb->mcsel不為0 

做GMC的處理 

Return 

計(jì)算運(yùn)動(dòng)向量dx,dy 

調(diào)用compensate16x16_interpolate進(jìn)行運(yùn)動(dòng)補(bǔ)償 

如果采用1/4像素運(yùn)動(dòng)估計(jì) 

略 

否則,調(diào)用get_ref計(jì)算用于運(yùn)動(dòng)補(bǔ)償?shù)膮⒖己陦K的指針 

調(diào)用4次transfer_8to16sub做亮度塊的運(yùn)動(dòng)補(bǔ)償,使得臨時(shí)數(shù)組里存放的是殘差,而原始圖像里存放的是參考快的數(shù)據(jù)。 

}//compensate16x16_interpolate 

計(jì)算出用于色差運(yùn)動(dòng)補(bǔ)償?shù)膁x,dy 

}//MODE_NOT_CODED或者M(jìn)ODE_INTER或者M(jìn)ODE_INTER_Q 

 

否則,那就是MODE_INTER4V 

根據(jù)是否使用1/4像素運(yùn)動(dòng)估計(jì),計(jì)算出4個(gè)色度塊的運(yùn)動(dòng)向量 

以這4個(gè)運(yùn)動(dòng)向量為參數(shù),調(diào)用4次compensate8x8_interpolate ,該操作類似于compensate16x16_interpolate,不同在于一次只計(jì)算一個(gè)塊。 

計(jì)算出用于色差運(yùn)動(dòng)補(bǔ)償?shù)膁x,dy 

 

調(diào)用CompensateChroma計(jì)算色差塊的運(yùn)動(dòng)補(bǔ)償 

調(diào)用interpolate8x8_switch2計(jì)算出u的插值 

調(diào)用interpolate8x8_halfpel_v或者interpolate8x8_halfpel_h或者interpolate8x8_halfpel_hv做實(shí)際的插值操作,或者直接返回 

調(diào)用transfer_8to16sub_c做u份量的運(yùn)動(dòng)補(bǔ)償 

 

調(diào)用interpolate8x8_switch2計(jì)算出v的插值 

調(diào)用interpolate8x8_halfpel_v或者interpolate8x8_halfpel_h或者interpolate8x8_halfpel_hv做實(shí)際的插值操作,或者直接返回 

調(diào)用transfer_8to16sub_c做v份量的運(yùn)動(dòng)補(bǔ)償 

}//CompensateChroma 

 

}//MBMotionCompensation 

 

如果需要編碼,那么用MBTransQuantInter進(jìn)行編碼,并把結(jié)果返回給pMB->cbp 

調(diào)用MBfDCT進(jìn)行宏塊變換編碼 

調(diào)用6次fdct 

 

調(diào)用MBQuantInter進(jìn)行量化 

對(duì)于宏塊里的每一塊 

調(diào)用quant_h263_inter進(jìn)行量化 

如果在量化后,前三個(gè)系數(shù)為0,并且系數(shù)的絕對(duì)值之和小于閥值,那么標(biāo)記該塊為全0塊,將標(biāo)記存入cbp。否則,標(biāo)記為非全0塊,也將標(biāo)記存入cbp 

}//MBQuantInter 

 

調(diào)用MBDeQuantInter反量化 

確定要使用的反量化函數(shù) 

對(duì)于六個(gè)塊里的每個(gè)塊,如果cbp表示許可,都調(diào)用dequant_h263_inter反量化 

}//MBDeQuantInter 

 

調(diào)用MBiDCT做反離散余弦變換 

對(duì)于六個(gè)塊里的每個(gè)塊,如果cbp表示許可,都調(diào)用idct_int32反量化 

 

調(diào)用MBTrans16to8將恢復(fù)出的殘差構(gòu)成重建圖像 

確定具體執(zhí)行的函數(shù),分為transfer_16to8copy和transfer_16to8add 

找到該宏塊的y,u,v分量起始地址 

對(duì)于六個(gè)塊里的每個(gè)塊,如果cbp表示許可,調(diào)用相應(yīng)得函數(shù)執(zhí)行重建。 

}// MBTrans16to8 

}//MBTransQuantInter 

 

如果無(wú)殘差,并且編碼方式為MODE_INTER,并且?guī)绞绞荘幀,并且向量2分量都為0,那么可以考慮skip模式 

如果可以考慮skip模式,則做進(jìn)一步檢驗(yàn),如果檢驗(yàn)通過(guò),那么 

編碼模式為MODE_NOT_CODED,并且在碼流里做標(biāo)記 

Continue 

 

調(diào)用MBCoding將這個(gè)宏塊寫入碼流 

寫入非NOT_CODED標(biāo)記 

調(diào)用CodeBlockInter寫入碼流 

編碼mcbpc 

編碼cbpy 

調(diào)用CodeVector編碼運(yùn)動(dòng)向量 

對(duì)六個(gè)塊,如果cbp只是需要編碼,調(diào)用CodeCoeffInter進(jìn)行編碼 

}//CodeBlockInter 

}// MBCoding 

 

}//對(duì)于每一個(gè)宏塊,依次執(zhí)行如下操作 

 

更新fcode 

為下一幀的編碼做簡(jiǎn)單的更新設(shè)置 

統(tǒng)計(jì)該幀編碼長(zhǎng)度 

}// FrameCodeP

您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP