Android硬體編解碼與軟體編解碼

来源:https://www.cnblogs.com/xiaoxiaoqingyi/archive/2018/02/27/8476839.html
-Advertisement-
Play Games

最近做了一個android項目用到編解碼功能。大概需求是:通過攝像頭拍攝一段視頻,然後抽幀,生成一個短視頻,以及倒序視頻,剛開始直接用 H.264 編碼格式,沒有使用MP4容器封裝。做了這些功能後,反而覺得使用MP4格式更加相容各機型,減少BUG出現。舉個明顯例子:在Android硬編的時候,常常會 ...


       最近做了一個android項目用到編解碼功能。大概需求是:通過攝像頭拍攝一段視頻,然後抽幀,生成一個短視頻,以及倒序視頻,剛開始直接用 H.264 編碼格式,沒有使用MP4容器封裝。做了這些功能後,反而覺得使用MP4格式更加相容各機型,減少BUG出現。舉個明顯例子:在Android硬編的時候,常常會用到 MediaCodec和MediaExtractor 相結合。但是,如果你用的 H.264 裸視頻文件,MediaExtractor 的 setSource 函數會報異常,它在某些機型(如魅族Note2,系統是5.1)無法解析該視頻文件。       得到大概的需求後,最初我們使用FFmpeg來做視頻編解碼,所謂軟體編解碼。由於在處理的過程中速率太慢,且需要在解碼後快速展示,所以該方案無法達到我們的預想效果(一個FFmpeg視頻解碼,並保存為jpeg例子:https://github.com/xiaoxiaoqingyi/ffmpeg-android-video-decoder)。但其也有一些優點,比如在相容方面,顏色轉換方面都做得很好,畢竟不是硬體編解碼(國內這麼多機型,你懂的),其次FFmpeg能輸出指定幀,而Android硬解(MediaCodec)不能輸出指定幀,需要輸入好幾幀到解碼器,才能解碼出一幀。目前我還是沒有找到輸入一幀解出一幀的方案,哪位大神知道的,可以指導指導。        在軟體編解碼不太適合的情況下,就只能考慮用硬體編解碼了(MediaCodec)。在前些日子,我參加了騰訊2017LIVE 直播開發者大會,瞭解到,現在的直播已經大部分使用硬體來編解碼了。剛說了,有些機型不能使用MediaExtractor來解析 h.264文件,為了相容大部分的機型,需要自己來解析,通過分析h.264文件的每一個位元組區分每一幀位置且是什麼類型幀。實現該需求,首先在從攝像頭獲取的數據,如果使用 Camera,一般設置為NV21格式, 但有些人使用Camera2,設置的格式是IMAGE。不管是哪種格式,最終都需要轉換成yuv420sp或yuv420p(註意:在轉碼時候,最好使用jni,用C/C++來轉格式,效率會高很多倍),才能供MediaCodec編碼,然後保存h.264文件。在創建MediaCodec實例化的時候,除了設置必須參數外,也要註意一些地方,比如,選擇哪種編碼器,一般情況會選擇如下:
 MediaCodec.createEncoderByType("video/avc");
這看上去其實沒什麼問題,大概原理就是獲取最優的Encoder,獲取Android系統中編碼器註冊表最前的一個,一般都是硬體解碼(MediaCodec也能調用軟體編解碼)。這樣創建編碼器其實不太靠譜,雖然官網也是這麼推薦,但是在國內眾多的Android機型中,有些手機就會出問題,有的編碼出現藍屏,有些直接就閃退了。有個國外的例子,大概的意思就是先獲取 "video/avc" 類型的編碼器,然後通過 try catch 一個個試驗,如果沒問題,就選用這個編碼器。源碼:https://github.com/ldm520/android_mediacodec_rtsp_h264 還有一個問題就是在設置 I 幀間隔的時候,有些手機不起作用,如下設置:
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, interval);
  針對這種情況,需要使用另外一種設置I幀的方式,強制設置:  
Bundle params = new Bundle();
params.putInt(MediaCodec.PARAMETER_KEY_REQUEST_SYNC_FRAME, 0);
mMediaCodec.setParameters(params);
  在編解碼時,當把所有的數據都輸入編解碼器的時候,要記得輸入結束符,編解碼器才會輸出所有的幀。       還有一個抽幀問題,如果使用MediaCodec來抽幀,生成一個新的視頻。是否可以直接把H.264文件里的幀去掉就行了?這樣不行的,通常會出現花屏。這需要重新把h.264文件輸入到解碼器,然後獲取到自己想要的幀,再輸入到一個新的編碼器中,生成你想要的H.264文件。在這裡還有一個格式問題,並不是從解碼器解碼出來的數據,就能直接使用編碼器來編碼,有部分手機可以,有些會出現藍屏,甚至閃退的情況。這時候需要統一解碼器處理的格式。如果你使用這種形式獲取:  
mMediaCodec.getOutputBuffer()
  出來的格式各種各樣,你很難去相容。google已經推出了一種新的格式:  
mMediaCodec.getOutputImage(outIndex)
  得出的是一個Image 對象,該對象可以保存為 JPEG格式圖片,也可以轉換成NV21(參考:http://www.cnblogs.com/welhzh/p/6079631.html),像上面拍攝部分,轉換成yuv422格式,再輸入到編碼器編碼。這樣不管什麼機型都可以相容了(我試用10多部不同廠商手機),雖然繞了很多彎路。           在使用MediaCodec還是遇到比較多的問題,畢竟官網都說它是一個輕量的編解碼器封裝。該總結適合使用過MediaCodec或有一定的解碼編碼經驗的童鞋們。如果你還沒瞭解過 MediaCodec,可以參考官網: https://developer.android.google.cn/reference/android/media/MediaCodec.html 或者中文翻譯版:http://blog.csdn.net/yssjz960427031/article/details/70050142        在使用MediaCodec的時候還遇到很多問題,這裡沒有一一列舉出來, 歡迎有遇到同樣問題或類似問題的童鞋留言討論!

   


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 2016年5月中旬,由於急著項目上線,cassandra3.4版本在沒有很多測試的情況下就使用了,當時部署在3台16G的windows系統伺服器上。幾個月使用下來,多數問題都是OOM導致的宕機 。特別是有一次宕機,在重啟資料庫後發現記憶體不斷上升,多次重啟也都是如此。通過觀察判斷可能原因是資料庫採取的 ...
  • 參考:https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sysmail-delete-mailitems-sp-transact-sqlhttps://docs.microsoft.c ...
  • 1,什麼是資料庫?——存儲數據的倉庫 資料庫技術是電腦應用領域中非常重要的技術,它產生於20世紀60年代末,是數據管理的最新技術,也是軟體技術的一個重要分支。 簡單的說,資料庫就是一個存放數據的倉庫,這個倉庫是按照一定的數據結構(數據結構是指數據的組織形式或數據之間的聯繫)來組織、存儲的,我們可以 ...
  • 一、前言 Redis是一個開源的使用ANSI C語言編寫、遵守BSD協議、支持網路、可基於記憶體亦可持久化的日誌型、key-Value 的資料庫、並提供多種語言的API。 通常,Redis 將數據存儲於記憶體中,或被配置為使用虛擬記憶體。通過兩種方式可以實現數據持久化:使用截圖的方式,將記憶體中的數據不斷寫 ...
  • 1.嵌套迴圈訪問的次數SYS@ PROD>create table t1( id number not null, n number, contents varchar2(4000) );SYS@ PROD>create table t2( id number not null, t1_id num ...
  • MySQL無法重啟、無法關閉、無法啟動、無法使用,如果是因為修改了主機名,可以這樣解決:關閉掉所有mysql進程,然後在啟動一些mysql! ...
  • IDENTITY_INSERT 為 ON 時 , 必須把需要插入的列名列出來 不然報錯 正確例子: SET IDENTITY_INSERT table(表名) ONinsert into table(id,name) value(1,名稱) SET IDENTITY_INSERT table OFF ...
  • 大家會發現一個空項目,從手機桌面打開app是秒啟動。但是對於自己開發的項目,有時會發現打開app的時候,會有短暫的1秒--2秒的白屏或者黑屏,然後才進入到程式界面。 個人理解為我們自己實現的Application文件裡面做了較多的初始化操作,當這些初始化操作完成後才進入到第一個Activity,這段 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...