Thực hiện mô phỏng giải thuật bằng phần mềm JSVM 9.19.14 [3] trên máy PC Intel(R) Core(TM) i5-2430M 2.4GHz, 4G RAM, Windows 7 Ultimate operating.
Tiến hành kiểm tra với quá trình mã hóa mở rộng chất lượng chuỗi ảnh FOREMAN 352x288 tốc độ 30f/s, số lượng frame mã hóa là 50.
Chế độ tìm kiếm toàn bộ block cho kết quả như sau:
Chế độ tìm kiếm mode nhanh cho kết quả như sau:
SUMMARY:
bitrate Min-bitr Y-PSNR U-PSNR V-PSNR --- --- --- --- --- 352x288 @ 1.8750 218.9738 107.6363 40.1523 43.1390 46.1069 352x288 @ 3.7500 293.7900 144.0214 39.1069 42.8361 45.6642 352x288 @ 7.5000 385.5738 188.2985 38.2307 42.6447 45.4049 352x288 @ 15.0000 483.1392 236.3808 37.6095 42.4970 45.2590 352x288 @ 30.0000 581.2080 289.7376 37.1921 42.4525 45.2411
Encoding speed: 28315.560 ms/frame, Time:1415778.000 ms, Frames: 50
SUMMARY:
bitrate Min-bitr Y-PSNR U-PSNR V-PSNR --- --- --- --- --- 352x288 @ 1.8750 218.9738 107.6363 40.1523 43.1390 46.1069 352x288 @ 3.7500 294.9043 144.3771 39.1095 42.8263 45.6769 352x288 @ 7.5000 388.3385 189.1477 38.2421 42.6603 45.4271 352x288 @ 15.0000 486.1536 236.9328 37.6106 42.5044 45.2692 352x288 @ 30.0000 583.9872 289.3680 37.1927 42.4586 45.2420
57
Hình 4.6 Ảnh Foreman trước khi mã hóa
58
Hình 4.8 Đồ thị đánh giá PSNR của 2 giải thuật Fast mode và Exhause block
Từ đồ thì chúng ta thấy rằng, giá trị PSNR tại cùng tốc độ bit của 2 giải thuật gần như tương đương nhau, tuy nhiên thời gian mã hóa của giải thuật Exhause block lớn gấp 15 lần giải thuật Fast mode. Do vậy giải thuật Fast mode đã giảm đáng kể thời gian cho bộ mã hóa.
59
PHỤ LỤC
1. Mở rộng không gian và chất lượng với Mode base layer được mã hóa intra
---Đoạn code của jsvm
MbEncoder::xEstimateMbIntraBL( IntMbTempData*& rpcMbTempData, IntMbTempData*& rpcMbBestData, UInt uiMinQP,
UInt uiMaxQP,
const Frame* pcBaseLayerRec, Bool bBSlice,
MbDataAccess* pcMbDataAccessBase ) {
ROF ( pcBaseLayerRec );
ROFRS( m_bBaseModeAllowedFlag, Err::m_nOK );
Bool bLowComplexMbEnable = m_bLowComplexMbEnable[rpcMbTempData- >getSH().getDependencyId()];
Bool bBLSkip = pcMbDataAccessBase->getMbData().isIntra(); YuvMbBuffer& rcYuvMbBuffer = *rpcMbTempData;
YuvMbBuffer& rcTempYuvMbBuffer = rpcMbTempData->getTempYuvMbBuffer(); MbDataAccess& rcMbDataAccess = rpcMbTempData->getMbDataAccess();
rpcMbTempData->clear(); rpcMbTempData->setMbMode( INTRA_BL ); rpcMbTempData->setBLSkipFlag( bBLSkip ); rpcMbTempData->setTransformSize8x8( false ); if( rpcMbTempData->getSH().getTCoeffLevelPredictionFlag() ) {
Bool bClipValue = m_pcTransform->getClipMode(); m_pcTransform->setClipMode( true );
if( pcMbDataAccessBase->getMbData().getMbMode() == MODE_PCM ) {
RNOK( xEstimateMbPCMRewrite( rpcMbTempData, rpcMbBestData ) ); }
else
{
for( UInt uiQp = uiMinQP; uiQp <= uiMaxQP; uiQp++ ) { switch( pcMbDataAccessBase->getMbData().getMbMode() ) { case INTRA_4X4: if( pcMbDataAccessBase->getMbData().isTransformSize8x8() == false ) {
RNOK( xEstimateMbIntra4 ( rpcMbTempData, rpcMbBestData, uiQp, bBSlice, bBLSkip ) );
} else
{
RNOK( xEstimateMbIntra8 ( rpcMbTempData, rpcMbBestData, uiQp, bBSlice, bBLSkip ) );
} break;
60
---Đoạn code thêm vào để chương trình tính mode Intra_4X4 trong trường hợp Mode Base layer là Intra
//---edit add---
RNOK( xEstimateMbIntra4 ( rpcMbTempData, rpcMbBestData, uiQp, bBSlice, bBLSkip ) );
//---end edit---
----Kết thúc phần thêm vào tính mode Intra_4X4
----Đoạn code của JSVM
case MODE_PCM: ROT(1); break; default:
RNOK( xEstimateMbIntra16 ( rpcMbTempData, rpcMbBestData, uiQp, bBSlice, bBLSkip ) ); break; } } } m_pcTransform->setClipMode( bClipValue );
m_pcTransform->setQp ( rcMbDataAccess, true ); return Err::m_nOK; } rpcMbTempData->setResidualPredFlag( false ); if( rcMbDataAccess.getSH().getSCoeffResidualPredFlag() ) { pcMbDataAccessBase->getMbTCoeffs().copyPredictionTo( rcYuvMbBuffer ); } else { rcYuvMbBuffer.loadBuffer( ((Frame*)pcBaseLayerRec)->getFullPelYuvBuffer() ); } rcTempYuvMbBuffer.loadLuma ( rcYuvMbBuffer ); rcTempYuvMbBuffer.loadChroma( rcYuvMbBuffer );
2. Mode base layer được mã hóa inter
//===== BASE LAYER MODE IS INTER ===== ----Đoạn code của JSVM
rpcMbTempData->clear ();
rpcMbTempData->copyMotion ( pcMbDataAccessBase->getMbData() ); rpcMbTempData->setBLSkipFlag ( true );
rpcMbTempData->getMbMvdData ( LIST_0 ).setAllMv( Mv::ZeroMv() ); rpcMbTempData->getMbMvdData ( LIST_1 ).setAllMv( Mv::ZeroMv() ); rpcMbTempData->setResidualPredFlag ( bResidualPred );
UInt uiNumMv = 0; Bool bBiPredForBlocksSmallerThan8x8 = false;
----Đoạn code thêm vào để hệ thống kiểm tra xem MB là chuyển động nhanh hay chuyển động chậm với mode base layer được mã hóa inter
//---edit add---
int length = 0;
MbMvData tempMbMv = rpcMbTempData->getMbMvdData(LIST_0); MbMvData tempMbMv1 = rpcMbTempData->getMbMvdData(LIST_1); for (int i=0; i < 16; i++)
61
{
int x = tempMbMv.m_acMv[i].getVer(); int y = tempMbMv.m_acMv[i].getHor(); length += (int)sqrtl(x * x + y * y); x = tempMbMv1.m_acMv[i].getVer(); y = tempMbMv1.m_acMv[i].getHor(); length += (int)sqrtl(x * x + y * y); }
----Đoạn code thêm vào để tính RDcost của các mode trong trường hợp MB là chuyển động chậm với mode base layer được mã hóa inter
if (length < 40)
{//---edit calculate 8x8, 4x4
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ ) {
UInt uiSListMv = 0;
switch( rpcMbTempData->getMbDataAccess().getMbData().getBlkMode( c8x8Idx.b8x8Index() ) )
{
case BLK_8x8: uiSListMv = 1; break; case BLK_8x4:
case BLK_4x8: uiSListMv = 2; break; case BLK_4x4: uiSListMv = 4; break; default: ROT(1);
}
UInt uiNumList = ( rpcMbTempData->getMbMotionData( LIST_0 ).getRefIdx( c8x8Idx.b8x8Index() ) > 0 ? 1 : 0 );
uiNumList += ( rpcMbTempData->getMbMotionData( LIST_1 ).getRefIdx( c8x8Idx.b8x8Index() ) > 0 ? 1 : 0 );
if( uiNumList == 2 && uiSListMv > 1 ) {
bBiPredForBlocksSmallerThan8x8 = true; }
uiNumMv += ( uiNumList * uiSListMv ); }
}
----Đoạn code thêm vào để tính RDcost của các mode trong trường hợp MB là chuyển động nhanh với mode base layer được mã hóa inter
else
{//---edit calculate all---
switch( rpcMbTempData->getMbDataAccess().getMbData().getMbMode() ) {
case MODE_16x16:
uiNumMv += ( rpcMbTempData->getMbMotionData( LIST_0 ).getRefIdx() > 0 ? 1 : 0 );
uiNumMv += ( rpcMbTempData->getMbMotionData( LIST_1 ).getRefIdx() > 0 ? 1 : 0 );
break;
case MODE_16x8: case MODE_8x16:
uiNumMv += ( rpcMbTempData->getMbMotionData( LIST_0 ).getRefIdx( PART_8x8_0 ) > 0 ? 1 : 0 );
uiNumMv += ( rpcMbTempData->getMbMotionData( LIST_0 ).getRefIdx( PART_8x8_3 ) > 0 ? 1 : 0 );
62
uiNumMv += ( rpcMbTempData->getMbMotionData( LIST_1 ).getRefIdx( PART_8x8_0 ) > 0 ? 1 : 0 );
uiNumMv += ( rpcMbTempData->getMbMotionData( LIST_1 ).getRefIdx( PART_8x8_3 ) > 0 ? 1 : 0 );
break;
case MODE_8x8: case MODE_8x8ref0: {
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ ) {
UInt uiSListMv = 0;
switch( rpcMbTempData->getMbDataAccess().getMbData().getBlkMode( c8x8Idx.b8x8Index() ) )
{
case BLK_8x8: uiSListMv = 1; break; case BLK_8x4:
case BLK_4x8: uiSListMv = 2; break; case BLK_4x4: uiSListMv = 4; break; default: ROT(1);
}
UInt uiNumList = ( rpcMbTempData->getMbMotionData( LIST_0 ).getRefIdx( c8x8Idx.b8x8Index() ) > 0 ? 1 : 0 );
uiNumList += ( rpcMbTempData->getMbMotionData( LIST_1 ).getRefIdx( c8x8Idx.b8x8Index() ) > 0 ? 1 : 0 );
if( uiNumList == 2 && uiSListMv > 1 ) {
bBiPredForBlocksSmallerThan8x8 = true; }
uiNumMv += ( uiNumList * uiSListMv ); } } break; default: ROT(1); } } //---edit end--- ---Kết thúc đoạn code thêm vào
3. Các mode ứng viên trong trường hợp thích nghi thời gian
---Đoạn code thêm vào để kiểm tra Mode tham chiếu chuyển động nhanh hay chậm và quyết định tính giá trị RDcost của mode tham chiếu bên trên, phía trái hay phía trước và phái sau.
m_acMvCandList.clear();
case TZ_SEARCH: {
/* if |mvPred| > 40)
** candlist = {above, left} */
/*Mv tempMv = rcMvPred;*/
long length = sqrtl(rcMvPred.getHor() * rcMvPred.getHor() + rcMvPred.getVer() * rcMvPred.getVer()); if ( length > 40) { rcMbDataAccess.addMvPredictors_2( m_acMvCandList ); } else { m_acMvCandList.push_back( rcMvPred );
63
//rcMbDataAccess.addMvPredictors( m_acMvCandList );
}
xTZSearch( pcRefPelData[0], cMv, uiMinSAD, m_bELWithBLMv ); } break; default: RERR(); break; } } cMv <<= 2;
64
KẾT LUẬN
Kỹ thuật mã hóa video thích nghi (SVC) là kỹ thuật tiên tiến bởi nó kế thừa các ưu điểm của các công nghệ nén video trước đó, đồng thời bổ sung những công cụ mã hóa hiệu quả hơn. Tuy vậy SVC chưa được ứng dụng rộng rãi trong ngành công nghiệp xử lý video do tính phức tạp và mới mẻ của nó. Do vậy, việc tìm hiểu và nghiên cứu về SVC là cần thiết.
Quá trình thực hiện luận văn giúp tôi bước đầu nắm bắt được nguyên lý hoạt động của công nghệ SVC nói riêng và hiểu thêm về các công nghệ mã hóa và xử lý video nói chung, tạo cơ sở và cũng mở ra nhiều hướng nghiên cứu sâu thêm về xử lý ảnh và video. Qua việc thực hiện luận văn này cũng trau rồi thêm được kỹ năng nghiên cứu khoa học.
Do thời gian hạn chế, đồng thời đây cũng là lần đầu tôi nghiên cứu về lĩnh vực xử lý ảnh, do vậy luận văn của tôi còn nhiều thiếu sót. Tôi rất mong nhận được sự góp ý của các thầy cô, đồng nghiệp và các bạn.
Một lần nữa tôi xin trân trọng cảm ơn Thầy giáo TS Lê Vũ Hà đã tận tình hướng dẫn, giúp tôi hoàn thành luận văn này.
65
TÀI LIỆU THAM KHẢO
Tiếng Anh
[1] Iain E. G. Richardson, “H.264 And MPEG-4 Video Compression”
[2] Recommendation ITU-T H.264 | ISO/IEC 14496-10:2009, ‘Advanced Video Coding for generic audio-visual services’, March 2009.
[3] Joint Scalable Video Model software, http://ip.hhi.de/imagecom
G1/savce/downloads/SVC-Reference-Software.htm.
[4] He Li, Z. G. Li, Changyun Wen, “Fast Mode Decision Algorithm for Inter-Frame Coding in Fully Scalable Video Coding” IEEE TRANSACTIONS ON CIRCUITS AND SYSTEMS FOR VIDEO TECHNOLOGY, VOL. 16, NO. 7, JULY 2006, pp.889 -895 [5] Iain E. Richardson, THE H.264 ADVANCED VIDEO COMPRESSION STANDARD
[6] The MPEG Handbook MPEG-1, MPEG-2, MPEG-4 – John Watklnson
[7] Heiko Schwarz, Detlev Marpe, Thomas Wiegand, “Overview of the Scalable Video Coding”, IEEE TRANSACTIONS ON CIRCUITS AND SYSTEMS FOR VIDEO TECHNOLOGY, VOL. 17, NO. 9, SEPTEMBER 2007, pp 1103 – 1119
Extension of the H.264/AVC Standard
[8] http://blog.mediacoderhq.com/h264-profiles-and-levels
[9] http://www.mathworks.com/