1. 程式人生 > >Android 利用MediaCodec 實現硬編碼 h264

Android 利用MediaCodec 實現硬編碼 h264

本篇文章記錄一下,Android呼叫mediacodec編碼camera回掉的YUV資料為h264的方法。

    由於公司需要,軟編碼(X264)由於手機效能的瓶頸,已不能滿足要求,所以決定使用硬編碼。其實硬編碼最早用過MediaRecord,但是不能直接得到h264資料,得先編成MP4,再從MP4裡把H264的NALU取出來,感覺太繞了,所以當時拋棄了MediaRecord,選擇了x264。不過看來,現在還得走上硬編碼的路了  --  MediaCodec

   這篇文章就用一個demo來說一下mediacodec的呼叫吧。

   首先,要獲取到CAMERA的回掉回來的YUV資料。

   其次,將獲得到的資料用MEDIACODEC編碼為H264。

   最後,將H264寫入檔案,程式結束後,可用VLC等支援播放H264的播放器檢視效果。

  先說下獲取YUV資料吧,這個很簡單了,直接上程式碼

  1. package com.example.mediacodecencode;  
  2. import java.io.IOException;  
  3. import java.util.ArrayList;  
  4. import java.util.concurrent.ArrayBlockingQueue;  
  5. import android.annotation.SuppressLint;  
  6. import android.annotation.TargetApi;  
  7. import android.app.Activity;  
  8. import android.graphics.ImageFormat;  
  9. import android.hardware.Camera;  
  10. import android.hardware.Camera.Parameters;  
  11. import android.hardware.Camera.PreviewCallback;  
  12. import android.media.MediaCodecInfo;  
  13. import android.media.MediaCodecList;  
  14. import android.os.Build;  
  15. import android.os.Bundle;  
  16. import android.util.Log;  
  17. import android.view.SurfaceHolder;  
  18. import android.view.SurfaceView;  
  19. publicclass MainActivity extends Activity  implements SurfaceHolder.Callback,PreviewCallback{  
  20.     private SurfaceView surfaceview;  
  21.     private SurfaceHolder surfaceHolder;  
  22.     private Camera camera;  
  23.     private Parameters parameters;  
  24.     int width = 1280;  
  25.     int height = 720;  
  26.     int framerate = 30;  
  27.     int biterate = 8500*1000;  
  28.     privatestaticint yuvqueuesize = 10;  
  29.     publicstatic ArrayBlockingQueue<byte[]> YUVQueue = new ArrayBlockingQueue<byte[]>(yuvqueuesize);   
  30.     private AvcEncoder avcCodec;  
  31.     @Override
  32.     protectedvoid onCreate(Bundle savedInstanceState) {  
  33.         super.onCreate(savedInstanceState);  
  34.         setContentView(R.layout.activity_main);  
  35.         surfaceview = (SurfaceView)findViewById(R.id.surfaceview);  
  36.         surfaceHolder = surfaceview.getHolder();  
  37.         surfaceHolder.addCallback(this);  
  38.         SupportAvcCodec();  
  39.     }  
  40.     @Override
  41.     publicvoid surfaceCreated(SurfaceHolder holder) {  
  42.         camera = getBackCamera();  
  43.         startcamera(camera);  
  44.         avcCodec = new AvcEncoder(width,height,framerate,biterate);  
  45.         avcCodec.StartEncoderThread();  
  46.     }  
  47.     @Override
  48.     publicvoid surfaceChanged(SurfaceHolder holder, int format, int width, int height) {  
  49.     }  
  50.     @Override
  51.     publicvoid surfaceDestroyed(SurfaceHolder holder) {  
  52.         if (null != camera) {  
  53.             camera.setPreviewCallback(null);  
  54.             camera.stopPreview();  
  55.             camera.release();  
  56.             camera = null;  
  57.             avcCodec.StopThread();  
  58.         }  
  59.     }  
  60.     @Override
  61.     publicvoid onPreviewFrame(byte[] data, android.hardware.Camera camera) {  
  62.         // TODO Auto-generated method stub
  63.         putYUVData(data,data.length);  
  64.     }  
  65.     publicvoid putYUVData(byte[] buffer, int length) {  
  66.         if (YUVQueue.size() >= 10) {  
  67.             YUVQueue.poll();  
  68.         }  
  69.         YUVQueue.add(buffer);  
  70.     }  
  71.     @SuppressLint("NewApi")  
  72.     privateboolean SupportAvcCodec(){  
  73.         if(Build.VERSION.SDK_INT>=18){  
  74.             for(int j = MediaCodecList.getCodecCount() - 1; j >= 0; j--){  
  75.                 MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(j);  
  76.                 String[] types = codecInfo.getSupportedTypes();  
  77.                 for (int i = 0; i < types.length; i++) {  
  78.                     if (types[i].equalsIgnoreCase("video/avc")) {  
  79.                         returntrue;  
  80.                     }  
  81.                 }  
  82.             }  
  83.         }  
  84.         returnfalse;  
  85.     }  
  86.     privatevoid startcamera(Camera mCamera){  
  87.         if(mCamera != null){  
  88.             try {  
  89.                 mCamera.setPreviewCallback(this);  
  90.                 mCamera.setDisplayOrientation(90);  
  91. 相關推薦

    Android 利用MediaCodec 實現編碼 h264

    本篇文章記錄一下,Android呼叫mediacodec編碼camera回掉的YUV資料為h264的方法。     由於公司需要,軟編碼(X264)由於手機效能的瓶頸,已不能滿足要求,所以決定使用硬編碼。其實硬編碼最早用過MediaRecord,但是不能直接得到h2

    android編碼h264資料,並使用rtp推送資料流,實現一個簡單的直播-MediaCodec(一)

      寫在前面:我並非專業做流媒體的coder,對流媒體行業無比崇拜,只是做了幾年安卓車載ROM,對安卓AV開發算是略懂。本篇部落格是我對MediaCodec編解碼和rtp推流的一次嘗試,希望能給有需要的朋友一些細微的幫助,不喜勿噴,如果有不對的地方希望大神指正共

    Android利用mediacodec進行視訊H264編碼解碼播放

    H264是目前最常用的視訊壓縮格式之一,可以將視訊、圖片、音訊等轉換為字串流形式,以此可以進行再次編輯、傳輸等。詳情參考http://blog.csdn.net/lcalqf/article/det

    Android利用ViewPager實現滑動放大縮小

    效果圖: 實現這個效果需要先處理佈局檔案 處理如下: ViewPager控制元件的父佈局需要設定  android:clipChildren="false" 這個屬性的解釋是Defines whether a child is limited to draw in

    Android 利用廣播實現黑名單【指定號碼】的簡訊的攔截 附原始碼下載連結

    Android 利用廣播實現指定號碼的簡訊的攔截 根據最近的學習內容,今天實現了利用廣播進行指定號碼的攔截 步驟: ①、寫一個數據庫的幫助類,實現對資料庫的建立,總共建立兩個資料庫psms(受保護的簡訊的資料庫)和protectedPhone(受保護的聯絡人資料庫),粘程式碼:

    Android 利用Java實現壓縮與解壓縮(zip、gzip)支援中文路徑

      zip扮演著歸檔和壓縮兩個角色;gzip並不將檔案歸檔,僅只是對單個檔案進行壓縮,所以,在UNIX平臺上,命令tar通常用來建立一個檔案檔案,然後命令gzip來將檔案檔案壓縮。   Java I/O類庫還收錄了一些能讀寫壓縮格式流的類。要想提供壓縮功能,只要把它們包

    Android 利用工具實現一鍵自動findViewById功能

    Android通過findViewById繫結檢視的方法,想必大家在Activity中已經用爛了。每次新建一個Activity類,一開始就需要呼叫findViewById方法給在xml佈局中定義並需要在程式碼中處理的View控制元件新增繫結。如果介面較為複雜,導致View元

    Android利用HttpURLConnection實現檔案上傳

    普通Java應用 瀏覽器在上傳的過程中是將檔案以流的形式提交到伺服器端的,如果直接使用Servlet獲取上傳檔案的輸入流然後再解析裡面的請求引數是比較麻煩,所以Java中Web端可以用的上傳元件有兩種: FileUpload【操作比較複雜】struts上傳的功能就是基於這個實現的。

    android利用PopupWindow實現點選工具欄彈出下拉選單

    package com.example.dropdownmenu; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.os.Bu

    #android 利用fragment實現模仿微信的例項

    圖片中給出了例項的效果,在點選下方的按鈕時,上半部分會自動切換成對應的內容。這裡使用的技術是fragment。 想必大家對fragment已經有所瞭解,就算不清楚,百度也有詳細的介紹。在這裡就著重介紹實現的過程。 首先,拿其中的一個部分“首頁”來

    C++利用boost實現base64編碼解碼

    #include <boost/archive/iterators/base64_from_binary.hpp> #include <boost/archive/iterators/binary_from_base64.hpp> #include &

    Android 利用popwindow實現類似下拉框效果

    1.實現思路。 利用popwindow的showAsDropDown方法,結合自定義background樣式。 2.java程式碼 PopupWindow searchConditionPopwind

    Android-利用動畫實現背景逐漸變暗

    前言 之前寫了一篇,介紹利用Handler動態改變背景透明度從而達到變暗的效果。現在補充一種方法,使用動畫來實現相同的效果。 ValueAnimator 和 Interpolator 今天的主角就是這倆,關於ValueAnimator和Interpol

    Android利用CircleImageView實現圓形頭像效果整理

    一、參考內容 根據上面大神的修改。但是使用方法已經變了。最先版本使用是 並且在build.gradle中新增依賴: compile 'de.hdodenhof:circleimageview:2.1.0' <de.hdodenhof.cir

    Android利用Achartengine實現實時曲線圖

    實時曲線圖在實際專案中經常會遇到,特別是與感測器相關的專案中。也正是因為公司專案需要實時展現從BLE裝置獲取到的心電圖資料,所以有機會對實時曲線圖的實現過程進行了較深入的探究。本文會講述兩種實現方式,其中每種實現方式裡都會包含兩種展現方式(曲線圖平移方向:左、右)。 假設

    Android利用vectordrawable實現軌跡動畫

    Google終於在Android5.0中引入了向量圖,向量圖的特點很多,比如不管怎麼放大都不會變形,大小也比png小很多,而且利用向量圖我們可以很簡單的實現一些看似很複雜的動畫效果雖然動畫看著挺

    Android利用FileDownloader實現APP自動更新並且安裝

    在Android中APP自動更新、安裝是必然的,最近呢我們公司也有這樣一個需求開始呢本菜鳥是打算用AppUpdate但是呢看了他的專案後發現真的是個好東西但是我不打算這樣做打算自己來實現更新、安裝。無意之間在一個專案中發現了FileDownloader這個真是

    Android利用RecyclerView實現列表倒計時效果

    只需要 過程 net looper 更新列表 code setimage update over 最近面試時,面試官問了一個列表倒計時效果如何實現,然後腦袋突然懵的了O(∩_∩)O,現在記錄一下。 運行效果圖 實現思路 實現方法主要有兩個: 1.為每個開始倒計時的it

    使用MediaCodec實現H264編碼「第四章,Android音視訊編碼那點破事」

      本章僅對部分程式碼進行講解,以幫助讀者更好的理解章節內容。 本系列文章涉及的專案HardwareVideoCodec已經開源到Github,支援軟編和硬編。使用它你可以很容易的實現任何解析度的視訊編碼,無需關心攝像頭預覽大小。一切都如此簡單。目前已迭代多個穩定版本,歡迎

    Android使用MediaCodec解碼播放H264格式視訊檔案

    前些時間,通過各種搜尋加請教了好幾個同行的朋友,在他們的指點下實現: RTSP+H264實時視訊播放播放及把實時視訊流儲存到手機SD卡中,再對儲存的H264格式檔案進行播放等基本功能。 非常感謝這些朋友的無私幫忙,在實現功能的同時,我也把他們提供的一