簡體   English   中英

使用MediaCodec進行H264流媒體

[英]Use MediaCodec for H264 streaming

我目前正在嘗試將Android用作Skype端點。 在這個階段,我需要將視頻編碼為H.264(因為它是Skype支持的唯一格式)並將其封裝在RTP中以使流式傳輸工作。

顯然, MediaRecorder由於各種原因並不適合這種情況。 一個是因為它在完成后添加了MP4或3GP標頭。 另一個原因是為了將延遲降至最低,硬件加速可能會派上用場。 這就是為什么我想利用最近對該框架的低級添加,即MediaCodecMediaExtractor等。

目前,我計划如下工作。 相機將其視頻寫入緩沖區。 MediaCodec使用H264對視頻進行編碼,並將結果寫入另一個緩沖區。 該緩沖區由RTP封裝器讀取,該封裝器將流數據發送到服務器。 這是我的第一個問題:這個計划聽起來對你有用嗎?

現在我已經陷入第一步了。 由於互聯網上關於使用相機的所有文檔都使用了MediaRecorder ,因此在編碼之前我找不到將原始數據存儲到緩沖區的方法。 addCallbackBuffer適合這個嗎? 任何人都有一個例子的鏈接?

接下來,我找不到很多關於MediaCodec的文檔(因為它相當新)。 有固定教程的人嗎?

最后:關於RTP庫的任何建議?

非常感謝提前!

UPDATE
我終於能夠從h264幀創建適當的RTP包。 這是你必須記住的(實際​​上很簡單):

編碼器確實為每個幀創建NAL標頭。 但它將每個幀作為h264 字節流返回。 這意味着每個幀以三個0字節和一個1字節開始。 您所要做的就是刪除那些開始前綴,並將幀放入RTP數據包(或使用FU-As將其拆分)。

現在回答你的問題:

在編碼之前,我找不到將原始數據存儲到緩沖區的方法。 addCallbackBuffer適合這個嗎?

您應該使用camera.setPreviewCallback(...),並將每個幀添加到編碼器。

我找不到很多關於MediaCodec的文檔(因為它相當新)。 有固定教程的人嗎?

這應該是關於MediaCodec如何工作的一個很好的介紹。 http://dpsm.wordpress.com/2012/07/28/android-mediacodec-decoded/

最后:關於RTP庫的任何建議?

我正在使用jlibrtp來完成工作。

我對MediaCodec或MediaExtractor一無所知,但我對MediaRecorder非常熟悉,並成功實現了基於SpyDroid的RTSP服務器,該服務器捕獲MediaRecorder的H264 / AMRNB輸出。 基本思想是代碼創建一個本地套接字對,並使用MediaRecorder的setOutputFile將輸出寫入該對中的一個套接字。 然后,程序從另一個套接字讀取視頻或音頻流,將其解析為數據包,然后將每個數據包包裝成一個或多個通過UDP發送的RTP數據包。

MediaRecorder確實在它完成后添加了MOOV標頭,但如果你以RTP格式提供H264視頻,這不是問題。 基本上,視頻流的開頭有一個“mdat”標題。 它有4個字節作為標題的長度,后跟4個字節“mdat”。 讀取長度以找出標頭的長度,驗證它是mdat標頭,然后跳過其余的標頭數據。 從那里開始,您將獲得一個NAL單元流,其單位長度為4個字節。 小型NAL單元可以在單個RTP數據包中發送,較大的單元可以分解為FU數據包。 對於RTSP,您還需要提供描述流的SDP標頭。 SpyDroid通過將非常短的電影寫入文件來計算SDP標頭中的信息,然后讀取此文件以從末尾提取MOOV標頭。 我的應用程序總是使用相同的大小,格式和比特率,所以我只提供一個靜態字符串:

public static final String SDP_STRING =
        "m=video 5006 RTP/AVP 96\n"
                + "b=RR:0\n"
                + "a=rtpmap:96 H264/90000\n"
                + "a=fmtp:96 packetization-mode=1;profile-level-id=428028;sprop-parameter-sets=Z0KAKJWgKA9E,aM48gA==;\n"
                + "a=control:trackID=0\n"
                + "m=audio 5004 RTP/AVP 96\n"
                + "b=AS:128\n"
                + "b=RR:0\n"
                + "a=rtpmap:96 AMR/8000\n"
                + "a=fmtp:96 octet-align=1;\n"
                + "a=control:trackID=1\n";

這是我的標題為640x480x10fps,H264視頻,具有8000/16/1 AMRNB音頻。

有一點我可以警告你:如果你正在使用MediaRecorder,你的預覽回調永遠不會被調用。 這僅適用於相機模式,而不適用於錄制視頻時。 在錄制視頻時,我無法找到以非壓縮格式訪問預覽圖像的任何方法。

我強烈建議查看SpyDroid的代碼。 這需要一些挖掘,但我打賭你想要的就是在那里。

您的計划絕對可行。 您可以注冊一個Camera.PreviewCallback,它將獲取圖片數據並將其放入MediaCodec。 您讀取輸出並將其作為RTP發送。 一般情況下這很容易,但是在不同的設備上存在各種缺陷,如無證的顏色空間和不同的MediaCodec行為,但它絕對是可能的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM