1. 程式人生 > >android 使用MediaCodec 編解碼總結(最全)

android 使用MediaCodec 編解碼總結(最全)

導言

本文將主要介紹在安卓中呼叫MediaCodec類實現視訊檔案的硬解碼,以及如何將以byte[]型別儲存的影象資料通過硬編碼合成視訊檔案。

1.MediaCodec類的編解碼原理

參考連結:https://developer.Android.com/reference/android/media/MediaCodec.html

工作流是這樣的: 以編碼為例,首先要初始化硬體編碼器,配置要編碼的格式、視訊檔案的長寬、位元速率、幀率、關鍵幀間隔等等。這一步叫configure。之後開啟編碼器,當前編碼器便是可用狀態,隨時準備接收資料。下一個過程便是編碼的running過程,在此過程中,需要維護兩個buffer佇列,InputBuffer 和OutputBuffer,使用者需要不斷出隊InputBuffer (即dequeueInputBuffer),往裡邊放入需要編碼的影象資料之後再入隊等待處理,然後硬體編碼器開始非同步處理,一旦處理結束,他會將資料放在OutputBuffer中,並且通知使用者當前有輸出資料可用了,那麼使用者就可以出隊一個OutputBuffer,將其中的資料拿走,然後釋放掉這個buffer。結束條件在於end-of-stream這個flag標誌位的設定。在編碼結束後,編碼器呼叫stop函式停止編碼,之後呼叫release函式將編碼器完全釋放掉,整體流程結束。

                             

2. 視訊解碼程式示例

程式碼來源於

以下所有程式碼可以在此處下載

[java] view plain copy  print?在CODE上檢視程式碼片派生到我的程式碼片
  1. package com.example.guoheng_iri.helloworld;  
  2. import android.graphics.ImageFormat;  
  3. import android.graphics.Rect;  
  4. import android.graphics.YuvImage;  
  5. import
     android.media.Image;  
  6. import android.media.MediaCodec;  
  7. import android.media.MediaCodecInfo;  
  8. import android.media.MediaExtractor;  
  9. import android.media.MediaFormat;  
  10. import android.util.Log;  
  11. import java.io.File;  
  12. import java.io.FileOutputStream;  
  13. import java.io.IOException;  
  14. import
     java.nio.ByteBuffer;  
  15. import java.util.concurrent.LinkedBlockingQueue;  
  16. publicclass VideoDecode {  
  17.     privatestaticfinal String TAG = "VideoToFrames";  
  18.     privatestaticfinalboolean VERBOSE = true;  
  19.     privatestaticfinallong DEFAULT_TIMEOUT_US = 10000;  
  20.     privatestaticfinalint COLOR_FormatI420 = 1;  
  21.     privatestaticfinalint COLOR_FormatNV21 = 2;  
  22.     publicstaticfinalint FILE_TypeI420 = 1;  
  23.     publicstaticfinalint FILE_TypeNV21 = 2;  
  24.     publicstaticfinalint FILE_TypeJPEG = 3;  
  25.     privatefinalint decodeColorFormat = MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible;  
  26.     privateint outputImageFileType = -1;  
  27.     private String OUTPUT_DIR;  
  28.     publicint ImageWidth=0;  
  29.     publicint ImageHeight=0;  
  30.     MediaExtractor extractor = null;  
  31.     MediaCodec decoder = null;  
  32.     MediaFormat mediaFormat;  
  33.     publicvoid setSaveFrames(String dir, int fileType) throws IOException {  
  34.         if (fileType != FILE_TypeI420 && fileType != FILE_TypeNV21 && fileType != FILE_TypeJPEG) {  
  35.             thrownew IllegalArgumentException("only support FILE_TypeI420 " + "and FILE_TypeNV21 " + "and FILE_TypeJPEG");  
  36.         }  
  37.         outputImageFileType = fileType;  
  38.         File theDir = new File(dir);  
  39.         if (!theDir.exists()) {  
  40.             theDir.mkdirs();  
  41.         } elseif (!theDir.isDirectory()) {  
  42.             thrownew IOException("Not a directory");  
  43.         }  
  44.         OUTPUT_DIR = theDir.getAbsolutePath() + "/";  
  45.     }  
  46.     publicvoid VideoDecodePrepare(String videoFilePath) {  
  47.         extractor = null;  
  48.         decoder = null;  
  49.         try {  
  50.             File videoFile = new File(videoFilePath);  
  51.             extractor = new MediaExtractor();  
  52.             extractor.setDataSource(videoFile.toString());  
  53.             int trackIndex = selectTrack(extractor);  
  54.             if (trackIndex < 0) {  
  55.                 thrownew RuntimeException("No video track found in " + videoFilePath);  
  56.             }  
  57.             extractor.selectTrack(trackIndex);  
  58.             mediaFormat = extractor.getTrackFormat(trackIndex);  
  59.             String mime = mediaFormat.getString(MediaFormat.KEY_MIME);  
  60.             decoder = MediaCodec.createDecoderByType(mime);  
  61.             showSupportedColorFormat(decoder.getCodecInfo().getCapabilitiesForType(mime));  
  62.             if (isColorFormatSupported(decodeColorFormat, decoder.getCodecInfo().getCapabilitiesForType(mime))) {  
  63.                 mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, decodeColorFormat);  
  64.                 Log.i(TAG, "set decode color format to type " + decodeColorFormat);  
  65.             } else {  
  66.                 Log.i(TAG, "unable to set decode color format, color format type " + decodeColorFormat + " not supported");  
  67.             }  
  68.             decoder.configure(mediaFormat, nullnull0);  
  69.             decoder.start();  
  70.         } catch (IOException ioe) {  
  71.             thrownew RuntimeException("failed init encoder", ioe);  
  72.         }  
  73.     }  
  74.     publicvoid close() {  
  75.         decoder.stop();  
  76.         decoder.release();  
  77.         if (extractor != null) {  
  78. 相關推薦

    android 使用MediaCodec 解碼總結

    導言 本文將主要介紹在安卓中呼叫MediaCodec類實現視訊檔案的硬解碼,以及如何將以byte[]型別儲存的影象資料通過硬編碼合成視訊檔案。 1.MediaCodec類的編解碼原理 參考連結:https://developer.Android.com/reference/and

    Android判斷Activity是否屏的方式!!!

    在Android中設定全屏的方式大致有兩種,一種是通過程式碼控制,一種是通過theme樣式配置。 那如何判斷一個Activity是不是全屏呢? 可以有以下幾種方式: 1.判斷window flag屬性(程式碼控制) if ( (activity.getWindow().getAttr

    細說show slave status參數詳解【轉】

    -c eol 通過命令 可能 id號 使用 padding register 正在 在搭建好mysql主從之後,我們一般在從庫上通過命令 show slave status\G 來查看主從的狀態,會有很多的參數,接下來筆者就帶大家好好的了

    JS幾種資料型別轉換

    一、轉為字串:使用 .toString或者String。 1、 .toString()方法:注意,不可以轉null和underfined //轉為字串-->toString方法 var bool=true; console.log(bool.toString()); //注意,toSt

    Eclise快捷鍵

    Eclipse常用快捷鍵 1幾個最重要的快捷鍵 程式碼助手:Ctrl+Space(簡體中文作業系統是Alt+/) 快速修正:Ctrl+1 單詞補全:Alt+/ 開啟外部Java文件:Shift+F2 顯示搜尋對話方塊:Ctrl+H 快速Outline:Ctrl+O

    centos7下mysql5.7修改密碼和外部能訪問的步驟、講解和所遇到的那些坑

    登入mysql報錯 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) 1、登入安裝資料庫的機器 輸入vi /etc/my.cnf,在該配置檔案增加一

    2018年Go語言實戰抽獎系統教程

    for 迴圈關鍵字 break 關鍵字 continue 關鍵字 len() 方法,會統計長度,也就是內容有多少(指下標位的總數) a = [1, 2, 3, 4] len(a) >>> 輸出結果為4,因為列表裡面有4個數值啊~~~ 1 2 3 依舊是昨天的作業,猜年齡,隨機出現一

    Vue全家桶+SSR+Koa2棧開發美團網已完結2018年

    1. SpringMVC Json互動   在 Java WEB 中經常用到 Json 資料來進行介面呼叫,傳遞資料,主要是因為 Json 格式的資料容易解析。SpringMVC支援 Json 格式的資料使用註解進行解析或轉為 Json。 2. SpringMVC Json 互動相關注解   @

    java設計模式精講 Debug 方式+記憶體分析已完結

    使用Exception物件 exception物件是Throwable子類的一個例項,只在錯誤頁面中可用。下表列出了Throwable類中一些重要的方法: 序號    方法&描述 1    public String getMe

    Spring Boot 2.0深度實踐之核心技術篇

    情見程式碼: #!/usr/bin/env python2 # -*- coding: utf-8 -*- """ Created on Sat Dec  2 15:40:35 2017 @author: 260207 """ from xlutils.copy import

    FFmpeg音視訊核心技術精講與實戰已完結2018

    1.背景 匿名內部類有以下問題: 語法過於冗餘 匿名類中的this和變數名容易使人產生誤解 型別載入和例項建立語義不夠靈活 無法捕獲非final的區域性變數 無法對控制流進行抽象 lambda表示式提供了輕量級的語法。 2.語法 lambda表示式的語法由引數列表、箭頭符號->和函式體

    React全家桶+AntD 共享單車後臺管理系統開發完整版2018

    實不相瞞對於我這樣的前端小白,去年用到React開發專案的時候也看過React-redux但是說實話沒有看他懂,後來用到的框架就是Vue所以沒怎麼研究React但是最近一直聽移動端的朋友說到React-Native所以想重新看看react-redux再看看React-Native。沒錯我就是這麼個善

    Socket網路程式設計進階與實戰更新至第九章2018

    1、 構造方法沒有返回型別,類方法有。 2、 類方法 static 所有物件 3、 繼承:extends 引用 /*  *如程式碼,問題: h4所指向的物件和h2所指向的物件,是否是同一個物件?  */ package basis; public class Hero&n

    Java併發程式設計高階技術-高效能併發框架原始碼解析與實戰已完結2018

    1.背景 匿名內部類有以下問題: 語法過於冗餘 匿名類中的this和變數名容易使人產生誤解 型別載入和例項建立語義不夠靈活 無法捕獲非final的區域性變數 無法對控制流進行抽象 lambda表示式提供了輕量級的語法。 2.語法 lambda表示式的語法由引數列表、箭頭符號->和函式體

    小白福音!零基礎入門軟體測試,首選必備課程 2018年

    要點:        1、在最新封裝的jQuery中,如果ajax請求的頁面有相同的部分直接省去了,只加載不一樣部分。        2、jQuery封裝有

    React 伺服器渲染原理解析與實踐已完結2018

    之前我的認知是,這是一個generator的語法糖,是用來解決非同步問題的,看起來寫起來是同步程式碼,但實際執行還是非同步的,感覺和他說的有點偏差,有偏差就說明至少有個人錯了;於是我打算重新認識一遍這個東西,說不定會有新收穫。 TALK IS CHEAP, SHOW YOU THE CODE.

    Spring原始碼解讀與設計詳析 2018

    預設情況: 通常情況下子級div在浮動的情況下,會對父級的div後面的元素佈局產生影響,因為div在浮動的情況下,會脫離正常的文件流導致父級的盒子不能被撐起。這樣父級的高度就可能是0,會影響整個佈局。程式碼和效果如下: 程式碼: <style>     

    深度學習在推薦系統中的應用綜述

    原文連結:https://arxiv.org/pdf/1707.07435.pdf摘要:隨著線上

    2018小白福音!零基礎入門軟體測試,首選必備課程

    第1章 課程介紹 本章將從軟體測試的起源與發展、測試行業的現狀及職業生涯規劃等整體做介紹。 1-1 課程介紹 1-2 軟體測試的發展 1-3 軟體測試的發展與職業規劃 1-4 軟體測試之“獨孤九劍” 第2章 軟體測試工程師必備基礎知識 本章將講解軟體的概念、軟體的生命週期、軟體測試方法、軟體測

    軟體設計師考試詳細介紹

    一 報名考試及複習 1 考試簡介 軟體設計師考試屬於全國計算機技術與軟體專業技術資格考試(即軟考)中的一箇中級考試。通過本考試的合格人員能根據軟體開發專案管理和軟體工程的要求,按照系統總體設計規格說明書進行軟體設計;能夠編寫程式設計規格說明書等相應的文件;能夠組織和指導程式