《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 嵌入式技术 > 业界动态 > 在TMS320C6711 DSP上实现H.263视频编码器的EDMA数据存取策略

在TMS320C6711 DSP上实现H.263视频编码器的EDMA数据存取策略

2008-10-15
作者:朱 飞 吴裕斌 曹丹华

  摘 要: 提出了在TMS320C6711 DSP平臺(tái)上實(shí)現(xiàn)H.263視頻編碼器的過程中,如何使用EDMA優(yōu)化數(shù)據(jù)存取的策略,從而減少了CPU花費(fèi)在數(shù)據(jù)搬移上的開銷。
  關(guān)鍵詞: H.263 DSP  EDMA QDMA 數(shù)據(jù)存取策略


  目前,將H.263算法在DSP芯片上實(shí)現(xiàn),已成為一種越來越廣泛的應(yīng)用趨勢(shì)。采用DSP實(shí)現(xiàn)H.263算法,相對(duì)于以往的方案,具有更好的擴(kuò)展性,可以很容易地將聲音編解碼和復(fù)用、通信協(xié)議添加進(jìn)來,綜合在一塊DSP芯片中,具有很強(qiáng)的實(shí)用性。
  本文采用TI公司的TMS320C6711 DSP實(shí)現(xiàn)H.263的編碼,提出一種在DSP平臺(tái)上充分合理使用片上EDMA控制器,進(jìn)行數(shù)據(jù)存取優(yōu)化的策略。
1 TMS320C6711的直接存儲(chǔ)器訪問控制器
  直接存儲(chǔ)器訪問(DMA)是C6000 DSP的一種重要的數(shù)據(jù)訪問方式,它可以在沒有CPU參與的情況下,由DMA控制器完成DSP存儲(chǔ)空間內(nèi)的數(shù)據(jù)搬移,數(shù)據(jù)搬移的源/目的地址可以在片內(nèi)存儲(chǔ)器、片內(nèi)外設(shè)" title="外設(shè)">外設(shè)和外部器件。
  在TMS320C6711中,EDMA控制器負(fù)責(zé)片內(nèi)存儲(chǔ)器L2和外設(shè)之間的數(shù)據(jù)傳輸,其增強(qiáng)之處在于:
  ·提供了16個(gè)通道
  ·通道間的優(yōu)先級(jí)設(shè)置
  ·支持不同結(jié)構(gòu)數(shù)據(jù)傳輸?shù)逆溄?QDMA除外)
  EDMA控制器是基于RAM結(jié)構(gòu)的,EDMA的參數(shù)RAM(PaRAM)存放著傳輸控制參數(shù)。圖1給出了一個(gè)PaRAM的內(nèi)部結(jié)構(gòu),總共6個(gè)字(32bit/word)。
  選項(xiàng)參數(shù)內(nèi)容如圖2所示。


  TMS320C6711 DSP還提供一種快速DMA(QDMA)傳輸方式" title="傳輸方式">傳輸方式。QDMA與EDMA相似,支持幾乎所有的EDMA傳輸模式,但是提交傳輸申請(qǐng)的速度要快很多。在應(yīng)用系統(tǒng)中,EDMA適合于固定周期的數(shù)據(jù)傳輸,但如果需要CPU干預(yù)控制搬移數(shù)據(jù),QDMA則比較適合。
  QDMA的操作由兩組寄存器進(jìn)行控制。第一組的五個(gè)寄存器寄存了QDMA傳輸所需的參數(shù),與EDMA的PaRAM類似,只是沒有重加載" title="加載">加載/鏈接參數(shù)。第二組的五個(gè)寄存器是第一組寄存器的“偽映射”。
  下面就H.263編碼的某些環(huán)節(jié)說明如何采用EDMA技術(shù)對(duì)編碼數(shù)據(jù)進(jìn)行優(yōu)化存取。
2 原始圖像的獲取
  由于待處理的原始圖像都很大,即使QCIF格式的圖像,也要占用38KB左右的存儲(chǔ)空間,顯然不能將待編碼圖像存放于片內(nèi)RAM(L2)中。通常的方法是在CPU干預(yù)下,采用“讀入-寫出”的方式,從視頻設(shè)備讀取數(shù)據(jù),然后存入片外SDRAM中。使用C6000 DSP強(qiáng)大的EDMA,亦可以實(shí)現(xiàn)原始圖像幀的后臺(tái)傳輸,EDMA無需CPU的干預(yù)便可獨(dú)自將視頻設(shè)備的輸出圖像直接送往片外SDRAM。這樣,CPU就可以將搬移數(shù)據(jù)的時(shí)間用于圖像編碼的工作。
  在這里使用C6000 DSP的EDMA控制器的QDMA功能。相對(duì)于EDMA的傳輸方式,QDMA的傳輸方式有著更快的申請(qǐng)?zhí)峤凰俣取?BR>  在片外SDRAM中開辟三塊幀緩沖區(qū)Frame1(首地址0xA0000000)、Frame2、Frame3。初始化階段,先提交三個(gè)QDMA請(qǐng)求(此時(shí)也可使用通常的數(shù)據(jù)搬移手段),將視頻序列的前三幀數(shù)據(jù)分別存入三塊幀緩沖區(qū)內(nèi),填滿幀緩沖區(qū)。接著開始對(duì)Frame1內(nèi)的圖像數(shù)據(jù)" title="圖像數(shù)據(jù)">圖像數(shù)據(jù)進(jìn)行編碼,該幀編碼結(jié)束后,對(duì)Frame2內(nèi)的圖像數(shù)據(jù)進(jìn)行編碼,F(xiàn)rame2成為當(dāng)前幀,而Frame1成為Frame2的先前幀,一旦Frame2編碼完畢,便對(duì)Frame3內(nèi)的圖像數(shù)據(jù)進(jìn)行編碼,同時(shí)立即提交一個(gè)新的QDMA請(qǐng)求,從視頻外設(shè)讀取一幀新的圖像數(shù)據(jù)到Frame1中(因?yàn)閷?duì)Frame3進(jìn)行編碼時(shí),F(xiàn)rame2作為先前幀,F(xiàn)rame1已經(jīng)不需要了)。待Frame3編碼完畢后,F(xiàn)rame2又不需要了,此時(shí)再提交一個(gè)新的QDMA請(qǐng)求,讀取新的一幀圖像數(shù)據(jù)到Frame2中。如此循環(huán),每編碼完畢一幀圖像,就提交一個(gè)新的QDMA請(qǐng)求,依次在對(duì)應(yīng)的幀緩沖區(qū)內(nèi)存放新的一幀圖像數(shù)據(jù)。這樣,從外設(shè)獲取當(dāng)前編碼圖像的下一幀與當(dāng)前圖像的編碼工作同時(shí)進(jìn)行,DSP每次都直接對(duì)圖像進(jìn)行編碼,而不需要再花費(fèi)開銷從外設(shè)讀取。


  要實(shí)現(xiàn)圖3所示的QDMA傳輸,有兩種等價(jià)的方式:
  ·1D-1D,幀同步傳輸
  ·1D-2D,陣列同步傳輸
  下面以圖3為例,給出采用1D-2D傳輸方式,將圖像數(shù)據(jù)送往Frame1中時(shí)所需提交的QDMA的具體參數(shù)設(shè)置。
  void submit_qdma(void)
  {
   EDMA_Config config;
  config.opt = (unsigned int)0x28A00001;
   config.src = (unsigned int)0x90010000;  // 視頻外設(shè)的數(shù)據(jù)口地址
 config.cnt = (unsigned int)((288-1)<<16 | 352);
 config.dst = (unsigned int)0xA0000000; //目的地址
   config.idx = (unsigned int)(352<<16); //數(shù)據(jù)單元索引忽略
   EDMA_qdmaConfig(&config);
  }
3 圖像宏塊" title="宏塊">宏塊編碼
  從上面已經(jīng)知道,圖像幀存放在片外SDRAM中。因此,在對(duì)I幀所有宏塊和P幀INTRA宏塊編碼時(shí),或?qū)幀INTER宏塊進(jìn)行運(yùn)動(dòng)估計(jì)時(shí),每個(gè)宏塊都要進(jìn)行片外存儲(chǔ)器訪問,會(huì)占用很大的CPU開銷。所以,最好將當(dāng)前待編碼的宏塊存放于片內(nèi)RAM中。這樣,整個(gè)宏塊的編碼就始終是片內(nèi)訪問,宏塊編碼子函MB_Encode在效率上就能夠提高12%左右。
  最直接的做法就是在片內(nèi)SRAM中事先開辟一個(gè)宏塊緩沖區(qū),將待編碼圖像當(dāng)前位置處的一個(gè)宏塊搬移到片內(nèi)RAM中的宏塊緩沖區(qū),之后再調(diào)用宏塊編碼子函MB_Encode。但是這樣仍然會(huì)浪費(fèi)一定的CPU時(shí)間在數(shù)據(jù)塊的搬移上,所以還具有改進(jìn)的余地。結(jié)合C6000 DSP強(qiáng)大的EDMA功能,提出了如下改進(jìn)方案:
  由于每個(gè)塊組(GOB)共有8448個(gè)字節(jié)數(shù)據(jù)(CIF),因此可以在片內(nèi)RAM中開辟兩個(gè)塊組緩沖區(qū),采用乒乓方式,通過啟動(dòng)EDMA塊組數(shù)據(jù),使用獨(dú)立于CPU的EDMA數(shù)據(jù)通道,在后臺(tái)從片外搬移到片內(nèi)。這樣一來,每次調(diào)用宏塊編碼時(shí),數(shù)據(jù)都已經(jīng)存放在指定緩沖區(qū)中,不僅無需做數(shù)據(jù)的搬移工作,而且還是在片內(nèi)進(jìn)行數(shù)據(jù)訪問。
  初始化時(shí),可以采用普通的數(shù)據(jù)搬移手段(亦可使用EDMA),從片外存儲(chǔ)器將第一幀圖像的前兩個(gè)塊組搬移到片內(nèi),充滿塊組緩沖區(qū),然后即可開始圖像編碼。在進(jìn)行圖像編碼的過程中,逐一對(duì)塊組的乒緩沖區(qū)中的宏塊進(jìn)行編碼,乒緩沖區(qū)宏塊編碼結(jié)束后,接著進(jìn)行乓緩沖區(qū)的宏塊編碼,同時(shí)啟動(dòng)EDMA,從片外存儲(chǔ)器搬移一個(gè)新的塊組到乒緩沖區(qū)來,使得編碼乓緩沖區(qū)和向乒緩沖區(qū)搬移塊組數(shù)據(jù)同時(shí)進(jìn)行,一旦乓緩沖區(qū)宏塊也編碼完畢,即可處理乒緩沖區(qū)中新的塊組,如此循環(huán)。
  C6000系列DSP的EDMA具有高效地從一幀圖像中抽取子幀的能力。以CIF格式的圖像為例,說明如何設(shè)置EDMA參數(shù)。
  如圖4所示左側(cè)表示4:2:0亞采樣的一幀YCrCb圖像,亮度分量首地址為A000 0000h,色度分量首地址分別是A0001 8C00h和A001 EF00h;右側(cè)表示塊組的乒乓緩沖區(qū),亮度分量y乒緩沖區(qū)首址在2000h,乓緩沖區(qū)首址在3600h,色度Cr分量的乒乓緩沖區(qū)首址分別為4C00h和5700h,色度Cb分量的乒乓緩沖區(qū)首址分別為5180h和5C80h。


  第一步,使用CPU啟動(dòng)EDMA通道,將一個(gè)GOB的亮度分量y傳輸?shù)紾OB亮度分量的乒緩沖區(qū)。CPU可以通過寫事件置位寄存器ESR啟動(dòng)一個(gè)EDMA通道,向ESR的某一位寫入“1”,強(qiáng)行觸發(fā)對(duì)應(yīng)事件,此時(shí)EDMA的PaRAM中的傳輸控制參數(shù)被送往地址發(fā)生器,開始對(duì)EMIF、L2和片外SDRAM進(jìn)行訪問。也可以使用QDMA進(jìn)行第一步數(shù)據(jù)傳輸,通過設(shè)置QDMA的結(jié)束代碼(選項(xiàng)參數(shù)的TCC字段)啟動(dòng)后續(xù)傳輸。
  第二步,EDMA通道完成了對(duì)GOB亮度分量的傳輸后,重新加載下一次傳輸所需要的傳輸控制參數(shù),將該GOB的色度分量Cr傳送到片內(nèi)對(duì)應(yīng)的Cr乒緩沖區(qū)。由于需要傳輸?shù)脑紨?shù)據(jù),在空間上不是連續(xù)存儲(chǔ)的,這里使用了C6000系列DSP的EDMA鏈接功能。鏈接功能可以將不同的EDMA傳輸控制參數(shù)連接起來,組成一個(gè)參數(shù)鏈,為同一個(gè)通道服務(wù)。一次EDMA傳輸任務(wù)結(jié)束后,會(huì)自動(dòng)從PaRAM中加載下一次傳輸所需要的參數(shù)。
  第三步,同上,將該GOB的Cb分量送入片內(nèi)對(duì)應(yīng)的Cb乒緩沖區(qū)。
  將GOB搬移到乒緩沖區(qū)對(duì)應(yīng)的EDMA通道的PaRAM設(shè)置參數(shù)如圖5所示。


  選擇幀同步、1D-2D數(shù)據(jù)傳輸類型,啟動(dòng)EDMA通道后,依次加載參數(shù)鏈,連續(xù)進(jìn)行三次EDMA數(shù)據(jù)傳輸之后,待編碼圖像的一個(gè)GOB即搬移到片內(nèi)的對(duì)應(yīng)緩沖區(qū)中。注意參數(shù)鏈的最后一個(gè)PaRAM,選項(xiàng)參數(shù)的LINK字段要設(shè)置為0。
  同樣可以得到將GOB搬移到乓緩沖區(qū)對(duì)應(yīng)的EDMA通道的PaRAM設(shè)置參數(shù),如圖6所示。


  下面給出向編碼塊組乒緩沖區(qū)傳輸數(shù)據(jù)的EDMA通道PaRAM參數(shù)鏈的配置程序。
  EDMA_Config  config;
  EDMA_Handle  hEdma_ping;   // 向乒緩沖區(qū)傳輸數(shù)據(jù)的EDMA通道句柄
  EDMA_Handle  hEdma_ping_tab1;  // 該通道的第一個(gè)鏈接PaRAM的句柄
  EDMA_Handle  hEdma_ping_tab2;  // 該通道的第二個(gè)鏈接PaRAM的句柄
  Uint32    link_tab1, link_tab2; // 該通道兩個(gè)鏈接PaRAM的地址
  if (EDMA_allocTableEx(1, &hEdma_ping_tab1))
  link_tab1= EDMA_getTableAddress(hEdma_ping_tab1);
  if (EDMA_allocTableEx(1, &hEdma_ping_tab2))
  link_tab2 = EDMA_getTableAddress(hEdma_ping_tab2);
  hEdma_ping = EDMA_open(EDMA_CHA_ANY, EDMA_
  OPEN_RESET);
  config.opt = (Uint32)0x55200003;  // 第一個(gè)PaRAM的選項(xiàng)參數(shù)
  config.src = (Uint32)0xA0000000;  // 待傳輸塊組Y分量的首地址
  config.cnt = (Uint32)0x000f0160;  //每行352像素,共16行
  config.dst = (Uint32)0x00002000;  // 設(shè)置在片內(nèi)的塊組緩沖區(qū)
  config.idx = (Uint32)0;      //源采用幀同步、2-D傳輸
  config.rld = (Uint32)(0x160<<16 | link_tab1 & 0xffff); // 鏈接到下一個(gè)PaRAM
  EDMA_config(hEdma_ping, &config);
  config.src = (Uint32)0xA00191880;
  config.cnt = (Uint32)0x000700B0;
  config.dst = (Uint32)0x00005700;
  config.rld = (Uint32)(0xB0<<16 | link_tab2 & 0xffff);// 鏈接到最后一個(gè)PaRAM
  EDMA_config(hEdma_ping_tab1, &config);
  config.opt = (Uint32) 0x55200001; // 最后一個(gè)PaRAM,LINK字段為0
  config.src = (Uint32)0xA001F480;
  config.dst = (Uint32)0x0005C880;
  config.rld = (Uint32)(0xB0<<16);
  EDMA_config(hEdma_ping_tab2, &config);
4 運(yùn)動(dòng)估計(jì)
  在P幀編碼中,對(duì)每個(gè)宏塊進(jìn)行運(yùn)動(dòng)估計(jì)時(shí),需要訪問存儲(chǔ)在片外存儲(chǔ)器的前一幀圖像??紤]到當(dāng)前幀的每個(gè)宏塊都是在前一幀的搜索窗口內(nèi)進(jìn)行運(yùn)動(dòng)估計(jì),所以可在片內(nèi)RAM中開設(shè)一個(gè)大小為48字節(jié)×48字節(jié)的緩沖區(qū),這個(gè)緩沖區(qū)對(duì)應(yīng)參考圖像幀中以當(dāng)前宏塊位置為中心的一個(gè)大小為48字節(jié)×48字節(jié)的窗口。
  依據(jù)與前面一樣的思想,這里同樣使用乒乓方式的搜索窗口緩沖區(qū)。在片內(nèi)RAM中開辟兩個(gè)48字節(jié)×48字節(jié)的搜索窗口緩沖區(qū),初始化時(shí),先將搜索窗口緩沖區(qū)充滿。第一次運(yùn)動(dòng)估計(jì)時(shí)參考搜索窗口乒緩沖區(qū);第二次運(yùn)動(dòng)估計(jì)時(shí)參考乓緩沖區(qū),此時(shí)提交一個(gè)QDMA請(qǐng)求,將下一宏塊需要的搜索窗口數(shù)據(jù)送往搜索窗口乒緩沖區(qū)。如此反復(fù),每次在參考某個(gè)搜索窗口緩沖區(qū)進(jìn)行運(yùn)動(dòng)估計(jì)時(shí),都提交一個(gè)QDMA請(qǐng)求,在后臺(tái)將下一宏塊的搜索窗口數(shù)據(jù)送入另一個(gè)搜索窗口緩沖區(qū)。
5 重建圖像幀
  本節(jié)實(shí)際上是圖像宏塊編碼的反過程,宏塊編碼時(shí)使用EDMA節(jié)省的是從片外SDRAM讀取圖像數(shù)據(jù)的開銷,而本節(jié)使用EDMA節(jié)省的是將重建數(shù)據(jù)幀從片內(nèi)L2存儲(chǔ)器寫到片外SDRAM的開銷。
  在片內(nèi)RAM中開辟兩個(gè)塊組緩沖區(qū),同樣采用乒乓方式,用于保存編碼過程中當(dāng)前編碼宏塊的重建數(shù)據(jù)。之所以開辟塊組大小的緩沖區(qū),而不是宏塊大小的緩沖區(qū),是為了防止過多的片內(nèi)與片外數(shù)據(jù)傳輸?shù)腅DMA要求。這一點(diǎn),圖像宏塊編碼也是一樣的。每當(dāng)乒塊組緩沖區(qū)的宏塊都重建完畢,就通過提交一個(gè)QDMA請(qǐng)求,將該塊組緩沖區(qū)內(nèi)的重建宏塊一次性復(fù)制到片外的重建幀緩沖區(qū)中,同時(shí)開始下一宏塊的重構(gòu),并將重構(gòu)宏塊放在乓塊組緩沖區(qū)。
  本文提出的幾個(gè)H.263編碼環(huán)節(jié),最自然的做法是CPU參與數(shù)據(jù)塊的搬移工作,然后再進(jìn)行下一步的工序。使用EDMA的數(shù)據(jù)訪問策略,可以減少CPU花費(fèi)在數(shù)據(jù)搬移上的開銷。在CPU和EDMA對(duì)片內(nèi)存儲(chǔ)器L2進(jìn)行各自獨(dú)立的訪問時(shí),可能并不是理想的同時(shí)進(jìn)行,有可能產(chǎn)生沖突。但是CPU對(duì)存儲(chǔ)器L2的訪問優(yōu)先級(jí)高于EDMA對(duì)L2的訪問優(yōu)先級(jí),而且即使出現(xiàn)EDMA在數(shù)據(jù)搬移完畢之前,DSP已經(jīng)處理完了上一步工序這樣一種最惡劣的情況,DSP也只需再稍微等待片刻即可。因?yàn)橐呀?jīng)有部分?jǐn)?shù)據(jù)傳輸完畢,所以整個(gè)數(shù)據(jù)搬移上耗費(fèi)的時(shí)間相對(duì)于不用EDMA只可能減少。如果設(shè)置合理,這個(gè)時(shí)間通常是零。
參考文獻(xiàn)
1 TMS320C6711 DSP Controllers Reference Guide.TI,2001
2 TMS320C6000 Optimizing C Compiler User’s Guide.TI,2001
3 Applications Using the TMS320C6000 Enhanced DMA.TI,2001
4 ITU-T DRAFT H.263. 2 May,1996
5 李方慧,王飛.TMS320C6000系列DSPs原理與應(yīng)用(第二版).北京:電子工業(yè)出版社,2002
6 沈蘭蓀,卓 力,田 棟,汪孔橋. 視頻編碼與低速率傳輸.北京:電子工業(yè)出版社,2002

本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點(diǎn)。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問題,請(qǐng)及時(shí)通過電子郵件或電話通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。

相關(guān)內(nèi)容