2013-06-20 105 views
2

我正在爲Android進行視頻壓縮項目,我正在考慮通過設計新的視頻編解碼器(從頭開始,我設計了該算法)來實現它。我已經閱讀了視頻壓縮的基礎知識,相關的相關算法和編解碼器基礎知識。我也發現,在Android上,FFmpeg可能是一個很好的解決方案。使用FFmpeg爲Android編寫自定義編解碼器

現在我的問題來了:

  1. 如何一個視頻編解碼器,如FFmpeg的?我在編寫編解碼器時仍然是初學者,但是 我該如何啓動?我有一個大概的想法,那就是你必須首先編寫至少一個分路器,然後編寫特定的編碼器和解碼器等。 (請求引用在這裏吧。)

  2. 由於我的編解碼器deosn't簡單地調整像幀,分辨率,碼率等 正在讀MediaCodec API和MediaPlayer的API在官方Android SDK足夠的視頻性能編寫新的編解碼器? (因爲上次我看到它只支持MPEG-4 SP,H.263和H.264,我無法找到是否可以直接編寫自己的類和函數)。

謝謝。

+0

是不是有人在那裏?請幫忙 。該項目的截止日期是關閉。 –

回答

2

您可以在Android上使用ffmpeg作爲工具或ffmpeg庫集(libavcodec,libaviformat,...)。您可以跨平臺的方式添加或更改ffmpeg編解碼器,因爲此項目非常重視平臺獨立性。您可以改用MediaCodec API。 但是沒有辦法擴展MediaCodec API更新有可能擴展MediaCodec,它記錄在http://source.android.com/devices/media.html#codecs)並且沒有簡單的方法讓ffmpeg使用這個API。

+0

感謝您的答覆。我最感到困擾的是我不知道如何使用PROGRAM編解碼器。用谷歌搜索ffmpeg文檔確實給了我一些結果,但它們作爲多媒體編程的新手並不可讀。任何關於ffmpeg的參考或如何從頭開始編寫編解碼器?再次感謝 。 –

+0

ffmpeg的架構在官方網站上有相當豐富的文檔,但我寧願建議您以現有的編解碼器爲基礎,並逐漸將其改爲執行您的任何打算。 –

+0

是的,感謝您的更新。但我想你提到的鏈接確實是一個硬件編解碼器,需要修改固件,這是目前無法完成的工作(我正在嘗試編寫一個軟件編解碼器)。我有一個想法,雖然...是否有可能通過添加編解碼器到mplayer實現編解碼器?有一些鏈接可以將定製編解碼器添加到mplayer中,但我不知道該怎麼做;(。請幫忙,再次感謝。 –

2

如果你是一個新手,並且「只想在SW中做」,而不是在SW中做。我假設您的算法不需要實時,並且可以動態壓縮視頻數據,或者您需要使用硬件編解碼器。

這是Android MediaCodec Reference

MediaCodec codec = MediaCodec.createDecoderByType(type); 
codec.configure(format, ...); 
codec.start(); 
ByteBuffer[] inputBuffers = codec.getInputBuffers(); 
ByteBuffer[] outputBuffers = codec.getOutputBuffers(); 
for (;;) { 
    int inputBufferIndex = codec.dequeueInputBuffer(timeoutUs); 
    if (inputBufferIndex >= 0) { 
    // fill inputBuffers[inputBufferIndex] with valid data 
    ... 
    codec.queueInputBuffer(inputBufferIndex, ...); 
    } 

    int outputBufferIndex = codec.dequeueOutputBuffer(timeoutUs); 
    if (outputBufferIndex >= 0) { 
    // outputBuffer is ready to be processed or rendered. 
    ... 
    codec.releaseOutputBuffer(outputBufferIndex, ...); 
    } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { 
    outputBuffers = codec.getOutputBuffers(); 
    } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { 
    // Subsequent data will conform to new format. 
    MediaFormat format = codec.getOutputFormat(); 
    ... 
    } 
} 
codec.stop(); 
codec.release(); 
codec = null; 

上寫着「// OutputBuffer中已準備好被處理或呈現」應用你的解碼器就行了。

這是你的第一幀將outputBuffers [0]輸出到outputBuffers [outputBufferIndex]。保存outputBufferIndex,即outputBufferIndex_old = outputBufferIndex;那麼你的下一幀將是outputbuffers [outputBufferIndex_old]到outputbuffers [outputBufferIndex]。但是,這是一個循環緩衝區,所以在for循環... AHHHHH

是這樣的:

//init 
int old = 0; 
int len = codec.BufferInfo().size,buff_len=outputBuffers.size; 
Byte[] processBuffer = new Byte[len]; 

... // outputBuffer ready 
for (int i=old; i<old+len; i++){ 
    processBuffer[i-old] = outputBuffers[i%buff_len]; 
} 
old = outputBufferIndex; 

Here就是一個很好的例子。您可能需要查看MediaMetadataRetriever以獲取有關輸入視頻的信息。高度和寬度等。如果您希望您的編碼器對不同類型的視頻具有較強的魯棒性,則每像素字節數。無論如何,這應該讓你開始。

我強烈建議使用Matlab(或GNU Octave)進行視頻編解碼器的原型設計。它會爲你節省很多時間。這意味着在嘗試在幾乎不可能的系統上實現它以像Android一樣進行調試之前,應確保您的預期編解碼器算法有效。

希望這會有所幫助。

0

如果有人碰到這個老問題絆倒的答案是:

  1. 編寫程序。
  2. 你想要「編解碼器」只需添加一個'空編解碼器'(複製輸入到輸出)。
  3. 測試您的程序仍然有效,並且您可以閱讀(所謂的)編碼文件。
  4. 添加Codec'null Codec'的編解碼器(調用函數以避免對工作文件進行大量編輯)。
  5. 重新測試您的程序以確保它仍然正常工作並讀取輸出以確保其正確。

就是這樣。 ;)

需要考慮的事情:

  • 「視頻播放器」可以丟棄幀,一個「錄像機」最好不要 丟幀。
  • 「軟件編解碼器」(無硬件輔助)將變慢, 在不同的Core上運行它(如果可用)。
  • 除非您僅製作 演示版,否則將需要硬件編解碼器(由軟件調用)。
  • 將您的程序拆分爲可以單獨運行的程序段,以便可以進行線程化,並且可以將這些線程分配給不同的內核。您需要檢測內核數量並評估其速度,以便您可以在運行時動態地進行一些分區。
  • 使用NDK和彙編語言編程將有必要獲得足夠的速度來以所需幀速率壓縮體面大小的視頻(IE:您不希望您的完成的程序僅支持320x176 @ 5 FPS視頻)。壓縮機必須運行得比輸入到達要快。
  • 設計自己的編解碼器擊敗現有的編解碼器(x265)將需要您幾年(沒有幫助)。
  • 如果您是Java,C和ARM Assembly(以及軟件工程師)的Wiz,則需要花費幾個月的時間;所以提交或退出。嘗試找到一些開放源代碼作爲開始的基礎。