當前位置:首頁 » 安卓系統 » android硬解碼h264

android硬解碼h264

發布時間: 2023-10-07 09:50:52

A. Android 音視頻01 --- H264的基本原理01

H264壓縮技術主要採用了以下幾種方法對視頻數據進行壓縮。包括:

解決的是空域數據冗餘問題。

解決的是時域數據冗徐問題

將空間上的相關性變為頻域上無關的數據然後進行量化。

經過壓縮後的幀分為:I幀,P幀和B幀:

關鍵幀,採用幀內壓縮技術。

向前參考幀,在壓縮時,只參考前面已經處理的幀。採用幀音壓縮技術。

雙向參考幀,在壓縮時,它即參考前而的幀,又參考它後面的幀。採用幀間壓縮技術。
除了I/P/B幀外,還有圖像序列GOP。

H264的基本原理其實非常簡單,下我們就簡單的描述一下H264壓縮數據的過程。通過攝像頭採集到的視頻幀(按每秒 30 幀算),被送到 H264 編碼器的緩沖區中。編碼器先要為每一幅圖片劃分宏塊。

劃分好宏塊後,計算宏塊的象素值。以此類推,計算一幅圖像中每個宏塊的像素值。

對於視頻數據主要有兩類數據冗餘,一類是時間上的數據冗餘,另一類是空間上的數據冗餘。其中時間上的數據冗餘是最大的。為什麼說時間上的冗餘是最大的呢?假設攝像頭每秒抓取30幀,這30幀的數據大部分情況下都是相關聯的。也有可能不止30幀的的數據,可能幾十幀,上百幀的數據都是關聯特別密切的。
H264編碼器會按順序,每次取出兩幅相鄰的幀進行宏塊比較,計算兩幀的相似度。如下圖:

在H264編碼器中將幀分組後,就要計算幀組內物體的運動矢量了。
H264編碼器首先按順序從緩沖區頭部取出兩幀視頻數據,然後進行宏塊掃描。當發現其中一幅圖片中有物體時,就在另一幅圖的鄰近位置(搜索窗口中)進行搜索。如果此時在另一幅圖中找到該物體,那麼就可以計算出物體的運動矢量了。
運動矢量計算出來後,將相同部分(也就是綠色部分)減去,就得到了補償數據。我們最終只需要將補償數據進行壓縮保存,以後在解碼時就可以恢復原圖了。壓縮補償後的數據只需要記錄很少的一點數據。
我們把運動矢量與補償稱為 幀間壓縮技術 ,它解決的是視頻幀在時間上的數據冗餘。除了幀間壓縮,幀內也要進行數據壓縮,幀內數據壓縮解決的是空間上的數據冗餘。

人眼對圖象都有一個識別度,對低頻的亮度很敏感,對高頻的亮度不太敏感。所以基於一些研究,可以將一幅圖像中人眼不敏感的數據去除掉。這樣就提出了幀內預測技術。
一幅圖像被劃分好宏塊後,對每個宏塊可以進行 9 種模式的預測。找出與原圖最接近的一種預測模式。然後,將原始圖像與幀內預測後的圖像相減得殘差值。再將我們之前得到的預測模式信息一起保存起來,這樣我們就可以在解碼時恢復原圖了,經過幀內與幀間的壓縮後,雖然數據有大幅減少,但還有優化的空間。

可以將殘差數據做整數離散餘弦變換,去掉數據的相關性,進一步壓縮數據。

上面的幀內壓縮是屬於有損壓縮技術。也就是說圖像被壓縮後,無法完全復原。而CABAC屬於無損壓縮技術。
無損壓縮技術大家最熟悉的可能就是哈夫曼編碼了,給高頻的詞一個短碼,給低頻詞一個長碼從而達到數據壓縮的目的。MPEG-2中使用的VLC就是這種演算法,我們以 A-Z 作為例子,A屬於高頻數據,Z屬於低頻數據。看看它是如何做的。
CABAC也是給高頻數據短碼,給低頻數據長碼。同時還會根據上下文相關性進行壓縮,這種方式又比VLC高效很多。

制定了相互傳輸的格式,將宏快 有組織,有結構,有順序的形成一系列的碼流。這種碼流既可 通過 InputStream 網路流的數據進行傳輸,也可以封裝成一個文件進行保存,主要作用是為了傳輸。

組成H264碼流的結構中 包含以下幾部分 ,從大到小排序依次是:
H264視頻序列,圖像,片組,片,NALU,宏塊 ,像素。

NAL層:(Network Abstraction Layer,視頻數據網路抽象層) : 它的作用是H264隻要在網路上傳輸,在傳輸的過程每個包乙太網是1500位元組,而H264的幀往往會大於1500位元組,所以要進行拆包,將一個幀拆成多個包進行傳輸,所有的拆包或者組包都是通過NAL層去處理的。
VCL層:(Video Coding Layer,視頻數據編碼層) : 對視頻原始數據進行壓縮

起始碼0x 00 00 00 01 或者 0x 00 00 01 作為 分隔符
兩個 0x 00 00 00 01之間的位元組數據 是表示一個NAL Unit。

I 幀的特點:

1.分組:把幾幀圖像分為一組(GOP,也就是一個序列),為防止運動變化,幀數不宜取多。
2.定義幀:將每組內各幀圖像定義為三種類型,即I幀、B幀和P幀;
3.預測幀:以I幀做為基礎幀,以I幀預測P幀,再由I幀和P幀預測B幀;
4.數據傳輸:最後將I幀數據與預測的差值信息進行存儲和傳輸。

1.更高的編碼效率:同H.263等標準的特率效率相比,能夠平均節省大於50%的碼率。
2.高質量的視頻畫面:H.264能夠在低碼率情況下提供高質量的視頻圖像,在較低帶寬上提供高質量的圖像傳輸是H.264的應用亮點。
3.提高網路適應能力:H.264可以工作在實時通信應用(如視頻會議)低延時模式下,也可以工作在沒有延時的視頻存儲或視頻流伺服器中。
4.採用混合編碼結構:同H.263相同,H.264也使用採用DCT變換編碼加DPCM的差分編碼的混合編碼結構,還增加了如多模式運動估計、幀內預測、多幀預測、基於內容的變長編碼、4x4二維整數變換等新的編碼方式,提高了編碼效率。
5.H.264的編碼選項較少:在H.263中編碼時往往需要設置相當多選項,增加了編碼的難度,而H.264做到了力求簡潔的「回歸基本」,降低了編碼時復雜度。
6.H.264可以應用在不同場合:H.264可以根據不同的環境使用不同的傳輸和播放速率,並且提供了豐富的錯誤處理工具,可以很好的控制或消除丟包和誤碼。
7.錯誤恢復功能:H.264提供了解決網路傳輸包丟失的問題的工具,適用於在高誤碼率傳輸的無線網路中傳輸視頻數據。
8.較高的復雜度:264性能的改進是以增加復雜性為代價而獲得的。據估計,H.264編碼的計算復雜度大約相當於H.263的3倍,解碼復雜度大約相當於H.263的2倍。
H.264的目標應用涵蓋了目前大部分的視頻服務,如有線電視遠程監控、交互媒體、數字電視、視頻會議、視頻點播、流媒體服務等。H.264為解決不同應用中的網路傳輸的差異。定義了兩層:視頻編碼層(VCL:Video Coding Layer)負責高效的視頻內容表示,網路提取層(NAL:Network Abstraction Layer)負責以網路所要求的恰當的方式對數據進行打包和傳送。

B. 在android 平台實現硬解的大俠們,你們是怎麼實現硬解碼的

1、視頻尺寸
一般都能支持176X144/352X288這種尺寸,但是大一些的,640X480就有很多機子不行了,至於為什麼,我也不知道。當然,這個尺寸必須和攝像頭預覽的尺寸一致,預覽的尺寸可以枚舉一下。
2、顏色空間
根據ANdroid SDK文檔,確保所有硬體平台都支持的顏色,在攝像頭預覽輸出是YUV12,在編碼器輸入是COLOR_FormatYUV420Planar,也就是前面代碼中設置的那樣。 不過,文檔終究是文檔,否則安卓就不是安卓。
在有的平台上,這兩個顏色格式是一樣的,攝像頭的輸出可以直接作為編碼器的輸入。也有的平台,兩個是不一樣的,前者就是YUV12,後者等於I420,需要把前者的UV分量顛倒一下。
byte[] i420bytes = null;
private byte[] swapYV12toI420(byte[] yv12bytes, int width, int height) {
if (i420bytes == null)
i420bytes = new byte[yv12bytes.length];
for (int i = 0; i < width*height; i++)
i420bytes[i] = yv12bytes[i];
for (int i = width*height; i < width*height + (width/2*height/2); i++)
i420bytes[i] = yv12bytes[i + (width/2*height/2)];
for (int i = width*height + (width/2*height/2); i < width*height + 2*(width/2*height/2); i++)
i420bytes[i] = yv12bytes[i - (width/2*height/2)];
return i420bytes;
}
3、輸入輸出緩沖區的格式
SDK里並沒有規定格式,但是,這種情況H264的格式基本上就是附錄B。但是,也有比較有特色的,它就是不帶那個StartCode,就是那個0x000001,搞得把他編碼器編出來的東西送給他的解碼器。
ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];
byte[] outData = new byte[bufferInfo.size + 3];
outputBuffer.get(outData, 3, bufferInfo.size);
if (frameListener != null) {
if ((outData[3]==0 && outData[4]==0 && outData[5]==1)
|| (outData[3]==0 && outData[4]==0 && outData[5]==0 && outData[6]==1))
{
frameListener.onFrame(outData, 3, outData.length-3, bufferInfo.flags);
}
else
{
outData[0] = 0;
outData[1] = 0;
outData[2] = 1;
frameListener.onFrame(outData, 0, outData.length, bufferInfo.flags);
}
}

C. 安卓開發怎麼將和h264文件解碼播放

如題所示,我想將攝像頭採集的數據進行h.264硬編碼,我想知道Android是如何對視頻數據進行硬體編碼的
目前已經知道的方案有:
1、用Android4.1 API MediaCodec來對視頻數據進行編碼

http://stackoverflow.com/q/17232477/2293921
此種方式我測試了,並未成功,目前一直卡在這里,如果你等幫助我,我將非常感激

2、通過MediaRecorder方式對數據進行編碼

具體可參考 http://blog.csdn.net/zblue78/article/details/6083374

3、通過移植ffmpeg

這種方式沒接觸過,也不了解

可能還有一些其他的方式來對視頻硬編碼,如果你了解一下,感謝分享!

綜上,我更傾向於1的方式去做

我來回答

Android , MediaCodec , 硬編碼

post_newreply

//$(\'note_\').focus();
function succeedhandle_vfastpost(url, message, param) {
$(\'vmessage\').value = \'\';
succeedhandle_fastpost(url, message, param);
showCreditPrompt();
}
var vf_tips = \'#在這里快速回復#\';
$(\'vmessage\').value = vf_tips;
$(\'vmessage\').style.color = \'#CDCDCD\';
$(\'vmessage\').onclick = function() {
if($(\'vmessage\').value==vf_tips) {
$(\'vmessage\').value=\'\';
$(\'vmessage\').style.color=\"#000\";
}
}
$(\'vmessage\').onblur = function() {
if(!$(\'vmessage\').value) {
$(\'vmessage\').value=vf_tips;
$(\'vmessage\').style.color=\"#CDCDCD\";
}
}
$(\'vreplysubmit\').onclick = function() {
if($(\'vmessage\').value == vf_tips) {
return false;
}
}

D. android h264硬編碼,得到流寫入文件後不能播放是怎麼回事

自己寫解碼264文件,如果用view顯示,就需要轉成bitmap顯示,或者使用opengl可以顯示yuv數據

如果已經保存成MP4格式的文件,就不需要解碼了,通過mediaplayer就能播

熱點內容
威綸編程軟體反編譯 發布:2025-01-24 19:30:26 瀏覽:48
網路存儲單元 發布:2025-01-24 19:28:04 瀏覽:167
自解c語言 發布:2025-01-24 19:27:08 瀏覽:646
安卓錄制的視頻為什麼有迴音 發布:2025-01-24 19:25:31 瀏覽:447
ip代理伺服器搭建 發布:2025-01-24 19:25:29 瀏覽:287
188腳本 發布:2025-01-24 19:25:19 瀏覽:820
電子商務搭建伺服器的模式 發布:2025-01-24 19:15:13 瀏覽:155
電腦怎麼連接伺服器存儲 發布:2025-01-24 19:13:32 瀏覽:351
qq郵箱傳文件夾怎麼傳 發布:2025-01-24 19:03:22 瀏覽:765
a5手動擋有哪些配置 發布:2025-01-24 19:03:10 瀏覽:418