国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

H264解碼學習-2015.04.16

2019-11-17 02:26:38
字體:
來源:轉載
供稿:網友

H264解碼學習-2015.04.16

  今天看了不少,卻感覺收獲寥寥。

  1、H264相關知識

  因為RTP協議發(fā)過來的數據已經經過了H264編碼,所以這邊需要解碼。補充一下H264的相關知識。

  與以往的視頻壓縮標準相比,H.264 視頻壓縮標準(簡稱H.264)具有更出色的性能,因此H.264 被稱為新一代視頻壓縮標準。H.264 與H.263 或MPEG-4 相比,       主要新增特性如下: 1、采用更為精細和豐富的幀內編碼及幀間預測方式,有效地減少殘差數據。 2、引入新的算術編碼方式,使得數據壓縮比更高。 3、視頻數據分層更為合理,引入 NAL 更利于網絡傳輸。  4、取消傳統(tǒng)的幀結構,引入 slice 結構和參數集,提高碼流的抗誤碼能力。  5、引入靈活的參考幀管理機制,參考幀數目最多可以達到 16 個。

  上述特性使得H.264 在視頻信噪比、圖像質量以及應用的靈活性上有了質的飛躍,但帶來的問題是H.264 在實現上復雜度較高。

  2、一些可能的解決方案(并未實踐)

  Intel media SDK,windows media sdk,http://www.ffmpeg-csharp.com/(這個網站上說是最簡單的方式使用ffmpeg,我也沒有學會怎么使用,等以后再回來學習吧),C#調用ffmpeg開發(fā)庫。以上這些方式只是搜索到的可能的解決方法,因為太懶了,著急做出東西,所以沒有去學習,后來在海康的播放庫API中看到H264的相關知識(http://www.survivalescaperooms.com/over140/archive/2009/03/22/1418946.html),以前做海康攝像頭調用的時候就經常看他的博客。最后在晚上的時候找到一種解決方式。使用海思提供的H264解碼庫,有專門的解碼庫,但也是用C++寫的。不過這沒有問題,想起以前海康攝像頭的時候也是C++的代碼,通過C#來調用。方法是通過PInvoke.net轉一下就可以了。

  轉換之后的代碼,將hi_h264dec_w.dll轉換為C#中的類(也是參考網上的代碼)

class Hi264Dec    {         public const int HI_SUCCESS = 0;         public const int HI_FAILURE = -1;         public const int HI_LITTLE_ENDIAN = 1234;         public const int HI_BIG_ENDIAN = 4321;         public const int HI_DECODER_SLEEP_TIME = 60000;         public const int HI_H264DEC_OK = 0;         public const int HI_H264DEC_NEED_MORE_BITS = -1;         public const int HI_H264DEC_NO_PICTURE = -2;         public const int HI_H264DEC_ERR_HANDLE = -3;          [DllImport("hi_h264dec_w.dll",EntryPoint = "Hi264DecImageEnhance", CallingConvention = CallingConvention.Cdecl)]         public static extern int Hi264DecImageEnhance(IntPtr hDec, ref hiH264_DEC_FRAME_S pDecFrame, uint uEnhanceCoeff);          [DllImport("hi_h264dec_w.dll",EntryPoint = "Hi264DecCreate", CallingConvention = CallingConvention.Cdecl)]         public static extern IntPtr Hi264DecCreate(ref hiH264_DEC_ATTR_S pDecAttr);          [DllImport("hi_h264dec_w.dll", EntryPoint = "Hi264DecDestroy", CallingConvention = CallingConvention.Cdecl)]         public static extern void Hi264DecDestroy(IntPtr hDec);          [DllImport("hi_h264dec_w.dll", EntryPoint = "Hi264DecGetInfo", CallingConvention = CallingConvention.Cdecl)]         public static extern int Hi264DecGetInfo(ref hiH264_LIBINFO_S pLibInfo);          [DllImport("hi_h264dec_w.dll", EntryPoint = "Hi264DecFrame", CallingConvention = CallingConvention.Cdecl)]         public static extern int Hi264DecFrame(IntPtr hDec, IntPtr pStream, uint iStreamLen, ulong ullPTS, ref hiH264_DEC_FRAME_S pDecFrame, uint uFlags);          [DllImport("hi_h264dec_w.dll", EntryPoint = "Hi264DecAU", CallingConvention = CallingConvention.Cdecl)]         public static extern int Hi264DecAU(IntPtr hDec, IntPtr pStream, uint iStreamLen, ulong ullPTS, ref hiH264_DEC_FRAME_S pDecFrame, uint uFlags);          [StructLayout(LayoutKind.Sequential)]         public struct hiH264_DEC_ATTR_S         {             public uint uPictureFormat;             public uint uStreamInType;             public uint uPicWidthInMB;             public uint uPicHeightInMB;             public uint uBufNum;             public uint uWorkMode;             public IntPtr pUserData;             public uint uReserved;         }          [StructLayout(LayoutKind.Sequential)]         public struct hiH264_DEC_FRAME_S         {             public IntPtr pY;             public IntPtr pU;             public IntPtr pV;             public uint uWidth;             public uint uHeight;             public uint uYStride;             public uint uUVStride;             public uint uCroppingLeftOffset;             public uint uCroppingRightOffset;             public uint uCroppingTopOffset;             public uint uCroppingBottomOffset;             public uint uDpbIdx;             public uint uPicFlag;             public uint bError;             public uint bIntra;             public ulong ullPTS;             public uint uPictureID;             public uint uReserved;             public IntPtr pUserData;         }          [StructLayout(LayoutKind.Sequential)]         public struct hiH264_LIBINFO_S         {             public uint uMajor;             public uint uMinor;             public uint uRelease;             public uint uBuild;             [MarshalAs(UnmanagedType.LPStr)] public string sVersion;             [MarshalAs(UnmanagedType.LPStr)] public string sCopyRight;             public uint uFunctionSet;             public uint uPictureFormat;             public uint uStreamInType;             public uint uPicWidth;             public uint uPicHeight;             public uint uBufNum;             public uint uReserved;         }          [StructLayout(LayoutKind.Sequential)]         public struct hiH264_USERDATA_S         {             public uint uUserDataType;             public uint uUserDataSize;             public IntPtr pData;             public IntPtr pNext;         }    }

    可以在窗體加載的時候加載如下代碼

//初始化,可以在 FormLoad 事務里完成             var decAttr = new Hi264Dec.hiH264_DEC_ATTR_S();             decAttr.uPictureFormat = 0;             decAttr.uStreamInType = 0;             decAttr.uPicWidthInMB = 480 >> 4;             decAttr.uPicHeightInMB = 640 >> 4;             decAttr.uBufNum = 8;             decAttr.uWorkMode = 16;             IntPtr _decHandle = Hi264Dec.Hi264DecCreate(ref decAttr);              Hi264Dec.hiH264_DEC_FRAME_S _decodeFrame = new Hi264Dec.hiH264_DEC_FRAME_S();             //解碼             //pData 為須要解碼的 H264 nalu 數據,length 為該數據的長度             if (Hi264Dec.Hi264DecAU(_decHandle, pData, (uint) length, 0, ref _decodeFrame, 0) == 0)             {                 if (_decodeFrame.bError == 0)                 {                     //策畫 y u v 的長度                     var yLength = _decodeFrame.uHeight * _decodeFrame.uYStride;                     var uLength = _decodeFrame.uHeight * _decodeFrame.uUVStride / 2;                     var vLength = uLength;                     var yBytes = new byte[yLength];                     var uBytes = new byte[uLength];                     var vBytes = new byte[vLength];                     var decodedBytes = new byte[yLength + uLength + vLength];                     //_decodeFrame 是解碼后的數據對象,里面包含 YUV 數據、寬度、高度等信息                     Marshal.Copy(_decodeFrame.pY, yBytes, 0, (int)yLength);                     Marshal.Copy(_decodeFrame.pU, uBytes, 0, (int)uLength);                     Marshal.Copy(_decodeFrame.pV, vBytes, 0, (int)vLength);                     //將從 _decodeFrame 中取出的 YUV 數據放入 decodedBytes 中                     Array.Copy(yBytes, decodedBytes, yLength);                     Array.Copy(uBytes, 0, decodedBytes, yLength, uLength);                     Array.Copy(vBytes, 0, decodedBytes, yLength + uLength, vLength);                     //decodedBytes 為yuv數據,可以將其轉換為 RGB 數據后再轉換為 BitMap 然后經由過程 PictureBox 控件即可顯示                     //這類代碼網上斗勁常見,我就不貼了     }

    在關閉的時候銷毀解碼器句柄

  

Hi264Dec.Hi264DecDestroy(_decHandle);

    在上面也說了,傳進來的數據轉為YUV數據后,還需要轉為RGB,再轉為圖片在控件中進行顯示。粗略從網上看了一下,這類算法還是比較多的,所以明天的目標是將視頻顯示出來。爭取讓已有的輪子跑起來。

    3、C++學習

    今天上午還看了一小部分C++,看的比較慢,學習了基本的輸入輸出語句,只看到第28頁。

    4、總結

    今天收畢業(yè)論文題目了,我還沒怎么開始寫呢。等把RTP和H264視頻解碼這一塊解決就開始準備畢業(yè)論文了。晚上的時候給周兆熊老師發(fā)的郵件已經收到回復。對于我自己目前的問題也總結一下:(1)語言的確沒什么再糾結的意思了,對我現在來說沒有孰優(yōu)孰劣,我需要的做的是盡量用熟悉的語言去解決現在存在的問題。(2)未來想找工作的話不單單需要專業(yè)方面的知識,也需要軟實力,想起前幾天犯得小錯誤,對自己的成長還是有幫助。需要繼續(xù)看書,讀過的書也需要做筆記。(3)關于怎么讓自己堅持去學習,前幾天的煩躁心里真的因為好好做事情減輕了呢。這幾天一直嘗試著用番茄工作法讓自己安定下來,堅持使用第四天,每天大約5個番茄鐘(效率好低啊)。看了高效工作后,里面的對拖延癥的分析三個原因真的讓我印象深刻:(1)其他人強迫你做的事情違背你的意愿(好像的確如此哈哈);(2)你給自己壓力要有完美的表現;(3)害怕犯錯誤受批評。三個原因真的是非常準確。不愉快也因為忙碌起來而漸漸消失了。

    5、現在所學的很多東西真的是流于表面,即使我把這個視頻解碼做出來已經能播放了,但我還是覺得自己的提升好少。但我還是要繼續(xù)這樣做,時間緊迫。不知道我寫的東西對您有沒有幫助,希望各位懂這方面的我們多多交流。對于我的建議給在評論中提出,謝謝您對我的提議。每天記錄一點點,就能進步一點點。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 酒泉市| 淮南市| 辽宁省| 邢台市| 上犹县| 彰化市| 洪雅县| 虎林市| 安西县| 兴安县| 麻栗坡县| 铜梁县| 阳信县| 闸北区| 响水县| 武隆县| 云林县| 吴江市| 莱芜市| 丹江口市| 武威市| 包头市| 健康| 河东区| 河北区| 泸西县| 新津县| 育儿| 都江堰市| 札达县| 长兴县| 清涧县| 平舆县| 桦南县| 盐源县| 新泰市| 朝阳县| 台中市| 长顺县| 石首市| 册亨县|