基於UDP協議的網絡攝像頭的關鍵問題解決及調試過程


一、摘要

  該篇博文主要對“基於UDP協議的網絡攝像頭的設計與實現”調試過程遇到的問題進行說明,並闡述其解決過程。

 

二、實驗平台

硬件平台:DIY_DE2

軟件平台:Quartus II 9.0 + Nios II 9.0 + Visual Studio 2008

 

三、實驗內容

  以VGA顯示作為參照,綜合調試,使C#端的視頻顯示正常。C#端的控件顯示分辨率為320*240。

1、初始圖像

圖1 初始圖片

       上圖是初步搭建完成的網絡攝像頭顯示效果,觀察視頻圖像,其具有以下特點:

(1)有一半的色彩未完全顯示;

(2)顯示的部分呈斜體狀,有鋸齒;

(3)顯示的部分分辨率降低為160*120,同(1);

(4)顯示的圖像的起始位置並非一幀圖像的開始,即圖像錯位。

2、解決圖像錯位的問題

  解決過程大致如下:

(1)首先,保證Quartus II端不變的情況下,在NIOS II端不讀取緩存在SRAM中的視頻數據,而是直接對待傳輸的數組賦一個定值,則C#端應顯示一個單色圖像。NIOS II的代碼如下,C#端的顯示效果如圖2所示。

NIOS II端測試代碼:

 

    for(j = 0;j < 76800;j++)

    {

        //a[j] = IORD(SRAM_16BIT_512K_0_BASE,j);

        //b[j] = IORD(SRAM_16BIT_512K_0_BASE,j) >> 8;

        a[j] = 0xff;

        b[j] = 0x03;

     }

 

 

圖2 C#端顯示單色圖像1

       上述圖像能夠驗證UDP傳輸正確和C#端的顯示程序正確。

(2)其次,保證NIOS II正常傳輸的基礎上,即不做剛才的改動,在Quartus II端壓縮子程序press_moudle模塊中,直接設定特定數據,觀察C#端顯示效果,效果如圖3所示。

 

圖3 C#端顯示單色圖像2

       這張圖像與圖1很相似,即有一半的色彩未正確顯示(因為是單色圖片,其他的特征不容易看出來)。根據圖2和圖3的對比,可以得知:圖像數據在讀寫SRAM時出了問題。到底是讀SRAM還是寫SRAM的問題?

       (3)再次,在NIOS II端,往SRAM里面寫特定數據,之后再讀取出來,最后通過網絡傳輸給PC,PC端用C#顯示,通過這個測試,可以發現NIOS II端讀SRAM沒有問題,因此,問題便可以確定為寫SRAM。

       (4)圖像錯位的問題可以定位為:開始往SRAM寫圖像數據時,當前數據並非一幀圖像的開始,即寫圖像數據的條件不正確。為了能夠正確的鎖存住幀開始信號,采用狀態機功能,關鍵代碼如下:

 

always@(posedge iclk or negedge rst_n)
begin
    if(!rst_n)
        test_out <= 0;
    else
    begin
        if((niosii_cmd) && (oVAL_VS == 2'b01))
        begin
            test_out <= ~test_out;
//            if(test_out)
//                rgb_zuhe <= rgb_zuhe + 1;
        end
//        else
//            test_out <= 0;
    end
end
always@(posedge iclk or negedge rst_n)
begin
    if(!rst_n)
    begin
//        oaddress <= 0;
        rd_en <= 0;
        rgb_zuhe <= 0;
    end
    else
    begin
        case(test_out)
        0:
        begin
            oaddress <= 0;
            rd_en <= 0;
            rgb_zuhe <= 0;
        end
        1:
        begin
            if(VGA_X_count[0] && VGA_Y_count[0] && oVAL_HS)
            begin
//                rgb_zuhe <= (rgb_zuhe + 1)%32;
                rgb_zuhe <= {1'b0,iR[9:5],iG[9:5],iB[9:5]};
                oaddress <= oaddress + 2;
                if(oaddress == 18'h257fe)
                begin
                    rd_en <= 1;
                    oaddress <= 0;
                end
            end
            else
                rd_en <= 0;
        end
        endcase
    end
end

  

  因為test_out的反轉,這里其實是隔一幀采一幀的結果。

  采用狀態機之后,圖像錯位的現象便得到解決,顯示效果如圖4所示。

 

圖4 解決圖像錯位的顯示效果

3、解決顯示部分分辨率降低的問題

  在Quartus II端的壓縮子程序press_moudle中,設定圖像數據為+1遞增的數據,在網絡抓包工具wireshark,收到的數據可以看出,數據是呈+2的形式遞增的,因此可以斷定,存儲的時候出現了問題。

       剛開始,以為SRAM存儲的時候是隔一個地址存儲一個數據,后分析一下,實則不然。因為在NIOS II讀取緩存在SRAM中的數據的時候,是挨個地址讀取的,而讀出來的數據確實呈+2的關系,說明:實際寫入SRAM的時候還是挨個地址寫的,只是寫控制器端問題。

       后查閱相關資料,16位數據的存儲器對應CPU時,地址線應左移一位,在系統的頂層文件中,並沒有將地址線左移,因此,造成了分辨率又一次的降低了1/4,解決辦法為,往SRAM存儲數據時,地址線每次+2即可(在第2步代碼中已有所體現)。顯示效果如圖5所示。

 

圖5 調試完成分辨率降低問題的效果

4、解決圖像偏斜的問題

(1)開始一直以為C#端繪圖部分的問題,經C#端寫buffer數據顯示,並認真分析顯示效果后,確定繪圖沒有問題。下面是分析過程。采用單色遞增進行分析。

C#端寫buffer測試代碼:

 

            for (int m = 0; m < num; m++)

            {

               if (m % 2 == 0)

                    buffer[m] = 0;

                else

                    buffer[m] = (byte)(((m - 1) * 2) % 128);

            }

 

  通過C#端調試,可以得知num=1468,即734個像素,按照320*240分辨率來算,一包數據可以繪制2行94個像素點,截取細節圖(圖5的左上部分),如圖6所示。

 

 

圖6 C#端測試細節圖

       由圖形可以看出,第一包數據剛好繪制了2行94個像素點,且3行的起始部分均正確對應,即均從純黑色開始,說明造成圖像傾斜的不是C#的問題。

(2)NIOS II測試,同樣采用單色遞增的方式進行驗證,同樣分析前2行94個像素點及以后的像素點,發現第95和96個像素點為非純黑色,而第97個像素點才開始為純黑色。這說明95和96像素點為其他的值,並非預期的像素值。

(3)仔細分析,發現最后2個像素點,即4個字節為一包數據的校驗位。NIOS II端發送一包數據的最大值為1510-42-4=1464,前42個字節為包頭,后4個字節為校驗位。而C#端在繪制圖像的時候是按照1468個字節來繪制的,因此,繪制的效果是,每次錯位2個像素點。在C#端繪制圖像的時候需要將num-4。改正后的顯示效果如圖7所示。

 

圖7 顯示效果

5、最后一個問題

  C#端控制底層發送視頻數據,即實現C#接收視頻數據時是從一幀圖像的開頭,而不是中間的某一包數據,否則,仍會造成圖像的錯位。但實現的過程出現一些問題。C#端發送命令,NIOS II通過中斷方式獲取命令時,則會出現以下兩種可能的問題:

(1)首先,NIOS II一直往PC發送數據,PC向NIOS II發送命令,NIOS II能夠正確收到命令數據,但是在PC不發送命令的時候,NIOS II端仍會進入中斷服務函數,接收到空命令或者是未知的多余命令,疑為PC會自動發送命令?這里的PC並非C#。

(2)NIOS II等待PC命令,PC發送命令,但是PC端的命令最多只能進入一次NIOS II的中斷服務函數。

  這個問題的本質其實就是PC和DM9000A互相發送數據,其中,DM9000A是通過中斷的方式接收PC發送下來的數據,但是DM9000A卻不能正常的接收到PC發送到數據。測試好久,仍沒有好的效果,難道是DM9000A中斷處理機制的問題?

  鑒於上述兩種均不理想的情況,系統采用另外一種解決辦法:

  NIOS II向PC發送視頻數據之前,先發送一包全是0的數據,一旦C#先解析出該包數據,便使能一個標志位,當該標志位使能后,開始繪制圖像。這能夠解決PC端圖像錯位的問題,但是不是最優的辦法。因為第一包數據為0的緣故,則顯示圖片的頂部有些許其他的色彩。如圖8所示。

 

圖8 最終的顯示效果

 

四、實驗總結

  最后通過wireshark測的傳輸速度為1Mbps,也就是說基於UDP協議的網絡攝像頭的幀率為1幀左右,分辨率為320*240。初步驗證了系統的可行性。由於視頻的幀率和分辨率均太小,下步將研究一下壓縮算法及在TCP傳輸協議上的實現。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM