精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

使用MediaCodec實現視頻解碼播放

移動開發 Android
MediaCodec解碼的過程包括配置、啟動、輸入數據、獲取解碼數據和渲染等步驟,通過這些步驟可以實現高效的音視頻解碼。

MediaCodec是Android平臺上的一個多媒體編解碼器,用于對音頻和視頻數據進行編解碼。它可以實現高效的音視頻編解碼,并且可以與硬件加速器結合使用,提高編解碼性能。MediaCodec可以用于錄制和播放音視頻,以及進行實時的音視頻通信等場景。

MediaCodec常用的方法:

  1. createDecoderByType(String mimeType):根據指定的MIME類型創建解碼器。
  2. createEncoderByType(String mimeType):根據指定的MIME類型創建編碼器。
  3. configure(MediaFormat format, Surface surface, MediaCrypto crypto, int flags):配置解碼器或編碼器的參數,包括媒體格式、渲染表面、加密等。
  4. start():啟動解碼器或編碼器。
  5. flush():清空解碼器或編碼器的輸入和輸出緩沖區。
  6. release():釋放解碼器或編碼器的資源。

MediaCodec解碼過程:

  1. 創建MediaCodec對象:首先需要創建一個MediaCodec對象,并指定要進行的編解碼操作(編碼或解碼)以及要使用的編解碼器類型。
  2. 配置MediaFormat:接下來需要配置MediaFormat,即指定要解碼的媒體數據的格式,包括媒體類型(音頻或視頻)、采樣率、比特率等參數。
  3. 配置Surface(可選):如果是視頻解碼,可以通過設置Surface來將解碼后的視頻數據直接渲染到Surface上,以實現視頻播放。
  4. 啟動MediaCodec:配置完成后,可以調用start()方法啟動MediaCodec。
  5. 輸入數據:接下來需要將要解碼的媒體數據傳遞給MediaCodec進行解碼。可以通過調用queueInputBuffer()方法將媒體數據傳遞給MediaCodec。
  6. 獲取解碼數據:MediaCodec會將解碼后的數據輸出到指定的Surface或ByteBuffer中,可以通過調用dequeueOutputBuffer()方法獲取解碼后的數據。
  7. 渲染(可選):如果是視頻解碼并且使用了Surface,解碼后的視頻數據會直接渲染到Surface上,如果是音頻解碼或者視頻解碼但不使用Surface,需要將解碼后的數據進行渲染或播放。
  8. 釋放資源:解碼完成后,需要釋放MediaCodec對象及相關資源。

MediaCodec解碼的過程包括配置、啟動、輸入數據、獲取解碼數據和渲染等步驟,通過這些步驟可以實現高效的音視頻解碼。

播放視頻

使用MediaCodec解碼本地h264文件并播放視頻。

  1. 創建一個MediaExtractor來讀取h264文件的數據流。
  2. 通過MediaFormat獲取視頻文件的格式信息,包括視頻的寬、高、幀率等參數。
  3. 創建一個MediaCodec來進行視頻解碼。
  4. 將解碼后的視頻幀渲染到Surface上進行播放。
// 創建MediaExtractor并指定要解碼的文件路徑
MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(path);

// 獲取視頻文件的格式信息
MediaFormat format = null;
for (int i = 0; i < extractor.getTrackCount(); i++) {
    format = extractor.getTrackFormat(i);
    String mime = format.getString(MediaFormat.KEY_MIME);
    if (mime.startsWith("video/")) {
        extractor.selectTrack(i);
        break;
    }
}

// 創建MediaCodec并配置解碼器
MediaCodec codec = MediaCodec.createDecoderByType(format.getString(MediaFormat.KEY_MIME));
codec.configure(format, surface, null, 0);
codec.start();

// 讀取并解碼視頻幀
ByteBuffer[] inputBuffers = codec.getInputBuffers();
ByteBuffer[] outputBuffers = codec.getOutputBuffers();
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
boolean isEOS = false;
while (!isEOS) {
    int inputBufferIndex = codec.dequeueInputBuffer(10000);
    if (inputBufferIndex >= 0) {
        ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
        int sampleSize = extractor.readSampleData(inputBuffer, 0);
        if (sampleSize < 0) {
            codec.queueInputBuffer(inputBufferIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
            isEOS = true;
        } else {
            codec.queueInputBuffer(inputBufferIndex, 0, sampleSize, extractor.getSampleTime(), 0);
            extractor.advance();
        }
    }

    int outputBufferIndex = codec.dequeueOutputBuffer(info, 10000);
    if (outputBufferIndex >= 0) {
        codec.releaseOutputBuffer(outputBufferIndex, true);
    }
}

// 釋放資源
codec.stop();
codec.release();
extractor.release();

具體實現:

// 解碼工具類

public class H264Player implements Runnable {

    // 本地 h264 文件路徑
    private String path;
    private Surface surface;
    private MediaCodec mediaCodec;
    private Context context;

    public H264Player(Context context, String path, Surface surface) {

        this.context = context;
        this.path = path;
        this.surface = surface;
        try {
            this.mediaCodec = MediaCodec.createDecoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);
            // 視頻寬高暫時寫死
            MediaFormat mediaFormat = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 368, 384);
            mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 15);
            mediaCodec.configure(mediaFormat, surface, null, 0);
        } catch (IOException e) {
            // 解碼芯片不支持,走軟解
            e.printStackTrace();
        }
    }


    public void play() {
        mediaCodec.start();
        new Thread(this::run).start();
    }

    @Override
    public void run() {
        // 解碼 h264
        decodeH264();
    }

    private void decodeH264() {
        byte[] bytes = null;
        try {
            bytes = getBytes(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 獲取隊列
        ByteBuffer[] byteBuffers = mediaCodec.getInputBuffers();
        int startIndex = 0;
        int nextFrameStart;
        int totalCount = bytes.length;

        while (true) {
            if (startIndex >= totalCount) {
                break;
            }
            MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
            nextFrameStart = findFrame(bytes, startIndex+1,totalCount);
            // 往 ByteBuffer 中塞入數據
            int index = mediaCodec.dequeueInputBuffer(10 * 1000);
            Log.e("index",index+"");
            // 獲取 dsp 成功
            if (index >= 0) {
                // 拿到可用的 ByteBuffer
                ByteBuffer byteBuffer = byteBuffers[index];
                byteBuffer.clear();
                byteBuffer.put(bytes, startIndex, nextFrameStart - startIndex);
                // 識別分隔符,找到分隔符對應的索引
                mediaCodec.queueInputBuffer(index, 0, nextFrameStart - startIndex, 0, 0);
                startIndex = nextFrameStart;

            }else {
                continue;
            }


            // 從 ByteBuffer 中獲取解碼好的數據
            int outIndex = mediaCodec.dequeueOutputBuffer(info,10 * 1000);
            if (outIndex > 0){
                try {
                    Thread.sleep(33);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                mediaCodec.releaseOutputBuffer(outIndex, true);
            }

        }
    }

    private int findFrame(byte[] bytes, int startIndex, int totalSize) {
        for (int i = startIndex; i < totalSize - 4; i++) {
            if (bytes[i] == 0x00 && bytes[i + 1] == 0x00 && bytes[i + 2] == 0x00 && bytes[i + 3] == 0x01) {
                return i;
            }

        }
        return -1;
    }


    /**
     * 一次性讀取文件
     *
     * @param path
     * @return
     * @throws IOException
     */
    public byte[] getBytes(String path) throws IOException {
        InputStream is = new DataInputStream(new FileInputStream(new File(path)));
        int len;
        int size = 1024;
        byte[] buf;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        buf = new byte[size];
        while ((len = is.read(buf, 0, size)) != -1)
            bos.write(buf, 0, len);
        buf = bos.toByteArray();
        return buf;
    }
    
    public void destroy(){
        if (mediaCodec != null) {
            mediaCodec.stop();
            mediaCodec.release();
        }
    }
}

播放視頻:

public class MainActivity extends AppCompatActivity {

    private H264Player h264Player;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        checkPermission();
        initSurface();
    }

    private void initSurface() {
        SurfaceView surfaceView = findViewById(R.id.surface);
        SurfaceHolder surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder surfaceHolder) {
                h264Player = new H264Player(MainActivity.this, new File(Environment.getExternalStorageDirectory(), "test.h264").getAbsolutePath(), surfaceHolder.getSurface());
                h264Player.play();
            }

            @Override
            public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
            }
        });
    }

    private boolean checkPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
                && checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.READ_EXTERNAL_STORAGE
            }, 1);
        }
        return false;
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 停止解碼器
        h264Player.destroy();
    }
}

上述代碼使用MediaCodec來解碼視頻流,并將解碼后的視頻渲染到SurfaceView上,在Activity銷毀時釋放MediaCodec資源。

責任編輯:武曉燕 來源: 沐雨花飛蝶
相關推薦

2024-02-28 08:22:07

2013-07-01 10:53:05

2022-03-06 20:02:21

監聽視頻播放

2022-08-26 12:13:08

APIjavascript視頻

2011-07-20 16:21:20

iPhone 視頻 播放器

2011-08-17 14:57:31

iPhone應用視頻播放

2022-03-24 15:00:09

Harmony編解碼鴻蒙

2021-08-30 07:49:32

Javascript西瓜視頻

2021-03-17 15:49:03

鴻蒙HarmonyOS應用

2023-08-26 19:07:40

VLC旋轉視頻

2021-10-29 07:49:23

Python彈幕播放

2011-08-10 15:58:58

iPhone視頻

2014-10-20 09:55:02

2022-08-16 17:37:06

視頻播放器鴻蒙

2022-04-26 14:33:21

鴻蒙操作系統

2021-07-13 09:27:20

AI 解碼視頻

2022-05-12 10:26:57

解碼器Linux

2022-04-15 11:30:59

代碼,Python保存視頻

2023-07-26 17:16:43

微軟Windows

2011-06-13 10:44:44

Qt Flash
點贊
收藏

51CTO技術棧公眾號

成人福利在线视频| 日本高清不卡一区| 国产成人一区二区三区免费看| 免费在线观看黄色av| 成人av动漫| 精品动漫一区二区| 日韩视频在线播放| www.五月天激情| 一本久道久久综合婷婷鲸鱼| 一本色道久久综合狠狠躁篇的优点| 亚洲一区在线不卡| 欧美videos另类精品| 91老司机福利 在线| 91精品视频在线免费观看| 国产午夜视频在线播放| 精品久久久久久久| 精品免费日韩av| 欧美婷婷精品激情| 爱情岛亚洲播放路线| 国产精品嫩草久久久久| 精品视频在线观看| 国产日韩一级片| 久久精品主播| 久久免费高清视频| 日本一级片免费| 免费成人av| 精品久久久久久久久久久久久久久 | 亚洲一级片在线看| 亚洲一级Av无码毛片久久精品| 日韩精品一区二区三区av| 亚洲综合丝袜美腿| 一卡二卡3卡四卡高清精品视频| 网站黄在线观看| 国产资源在线一区| 国产精品爽爽爽爽爽爽在线观看| 天海翼一区二区| 你懂的视频一区二区| 伊人久久久久久久久久久| 变态另类丨国产精品| 视频免费一区二区| 男人av在线播放| 国产一区二区精品在线观看| 国产精品高潮呻吟久久av野狼| 国产精久久久久久| 欧美一区在线看| 精品国产一区二区三区在线观看| 亚洲AV无码国产成人久久| 精品欧美午夜寂寞影院| 欧美成人三级在线| 污视频在线观看免费网站| 日本国产欧美| 色噜噜夜夜夜综合网| 久久精品国产精品亚洲色婷婷| 波多野结衣中文在线| 一区二区三区四区精品在线视频 | 在线观看a视频| 欧美有码在线| 精品欧美久久久| 特黄特黄一级片| 国产成人精品综合久久久久99| 日韩精品视频在线观看一区二区三区| 国产成人av电影免费在线观看| 92裸体在线视频网站| 99精品视频在线播放免费| 麻豆国产91在线播放| 国产精品网站入口| 亚洲视频中文字幕在线观看| 欧美96一区二区免费视频| 国产精品白丝jk喷水视频一区| 日韩黄色一级视频| 免费成人在线网站| 成人久久精品视频| 成人av免费播放| av影院午夜一区| 激情伦成人综合小说| 深夜视频在线免费| 国产午夜精品一区二区| 一区二区三区精品国产| av免费在线免费观看| 亚洲国产日韩一区二区| 国产精品视频一区二区三区四区五区| 中文字幕12页| 在线观看av免费| 亚洲一区影音先锋| 欧美日韩二三区| 日韩美女在线看免费观看| 欧美午夜精品一区二区蜜桃| 6080国产精品| 久久久久97| 一区二区亚洲欧洲国产日韩| 一级片黄色录像| 欧美婷婷在线| 日本亚洲欧美成人| 国产精品午夜福利| 99这里只有精品| 香蕉久久夜色| 2020国产在线视频| 欧美色videos| xx欧美撒尿嘘撒尿xx| 99精品国产一区二区三区2021| 亚洲精品中文字幕av| 女性裸体视频网站| 国产视频亚洲| 91精品在线国产| 视频三区在线观看| 91沈先生播放一区二区| 可以免费看毛片的网站| 2020日本不卡一区二区视频| 亚洲一区不卡在线| 成年人视频免费在线播放| 黑人巨大精品| 中文字幕一区二区三区在线播放 | 日本午夜精品久久久| 国产亚洲精品高潮| 久久久久亚洲天堂| 免费观看成人av| 国产美女99p| 五月香视频在线观看| 五月综合激情婷婷六月色窝| 亚洲久久中文字幕| 日韩激情网站| 欧美成人精品xxx| 亚洲欧美一二三区| 中文字幕1区2区| 91福利精品在线观看| 欧美videos中文字幕| 特级西西www444人体聚色| 亚洲一区二区三区无吗| 日本精品久久久久久久| 国产福利第一页| 国产日产精品一区| 国产在线播放观看| 欧美精品韩国精品| 欧美三级午夜理伦三级在线观看| 伊人伊人伊人久久| 国产一级特黄视频| 国内精品不卡在线| 日韩欧美一区二区三区四区 | 久久看人人爽人人| 久久成人福利视频| 一本色道69色精品综合久久| 久久精品久久久久久| 亚洲综合成人av| 久久久久久久免费视频了| 草草视频在线免费观看| 一区二区三区在线免费看| 久久久av一区| 91久久久久久久久久久久| 亚洲国产精华液网站w| 成人三级视频在线播放 | 日本在线视频不卡| 成人免费影院| 欧美一级在线亚洲天堂| 国产嫩草一区二区三区在线观看| 国产黄色片在线播放| 红桃av永久久久| 蜜臀av粉嫩av懂色av| 国产日韩综合av| 欧美日韩视频在线一区二区观看视频| 视频在线这里都是精品| 欧美一区二区在线观看| 日本成人免费在线观看| 国产一区二区三区在线视频观看| 亚洲人成免费网站| 91深夜福利视频| 国产在线激情| 欧美一区二区福利在线| 青娱乐免费在线视频| 国产成人av电影在线| 久久国产午夜精品理论片最新版本| 97品白浆高清久久久久久| 欧美激情a在线| 神马午夜在线观看| 日韩欧美在线网址 | 国产精品久久久久久久久免费高清| 日韩欧美一二区| 国产欧美日本在线| 中国字幕a在线看韩国电影| 亚洲美女av在线播放| 成人a v视频| 国产精品免费人成网站| 操人视频免费看| 在线日韩电影| 国产探花在线精品| 欧美激情精品久久久久久久变态| 超碰97在线人人| 精品欧美不卡一区二区在线观看| 色噜噜狠狠成人网p站| 午夜视频在线观看一区| 精品少妇无遮挡毛片| 日韩欧美高清| 不卡一区二区三区四区五区| 深夜成人在线| 神马国产精品影院av| 亚洲黄色在线免费观看| 一本色道久久综合精品竹菊| 久久精品亚洲a| a级精品国产片在线观看| 国产一二三四在线视频| 一区二区三区四区日韩| 久久精品国产美女| 日韩黄色三级| 91国内免费在线视频| 日本在线观看免费| 亚洲大胆人体视频| 国产精品自拍第一页| 一级中文字幕一区二区| 亚洲自拍偷拍图| 高清国产午夜精品久久久久久| 免费日韩中文字幕| 激情综合中文娱乐网| 亚洲一区二区不卡视频| 日日天天久久| 91视频九色网站| 快播电影网址老女人久久| 欧美激情一区二区三区成人| fc2在线中文字幕| 亚洲精品91美女久久久久久久| 91成人国产综合久久精品| 精品女同一区二区三区在线播放| 日本少妇aaa| 97精品中文字幕| 欧美日韩国产高清一区二区三区| 精品无码一区二区三区蜜臀| 久久亚洲一区二区三区明星换脸| 无码国产精品一区二区高潮| 美国欧美日韩国产在线播放| 18禁免费观看网站| 国产精品av久久久久久麻豆网| 亚洲一卡二卡| 成人激情在线| 欧美人与性禽动交精品| 久草在线综合| 国产精品久久久一区二区三区| www.久久久久爱免| 国产欧美日韩高清| gogo亚洲高清大胆美女人体| 性色av香蕉一区二区| 国产网红在线观看| 美女久久久久久久久久久| 欧美三级黄网| 综合av色偷偷网| 国产在线视频网址| 亚洲欧美日韩另类| 色av男人的天堂免费在线| 精品电影一区二区| 成人午夜精品福利免费| 日韩欧美国产一区在线观看| 99视频国产精品免费观看a | 国产在线观看欧美| 亚洲一区在线| 欧美另类videos| 一区二区三区四区日韩| 日本a级片在线观看| 久久精品欧美一区| 丁香色欲久久久久久综合网| 欧美精品一卡| 成品人视频ww入口| av成人毛片| 内射国产内射夫妻免费频道| 亚洲综合二区| www黄色av| 日韩中文字幕亚洲一区二区va在线| 日本999视频| 美女高潮久久久| 亚洲精品国产久| 国产成人午夜视频| 大乳护士喂奶hd| 久久人人爽人人爽| 精品手机在线视频| 亚洲精品免费电影| 国产精品7777777| 91国模大尺度私拍在线视频| 亚洲视频在线观看一区二区| 欧美一区二区不卡视频| 欧美一级淫片免费视频魅影视频| 亚洲精品视频播放| 成人p站proumb入口| 国产精品亚洲成人| 国产有码一区二区| 国产精品成人3p一区二区三区| 亚洲xxx视频| 日本精品影院| 亚洲人成网站在线播放2019| 亚洲精品91| 成人免费在线小视频| 久久国内精品视频| 国产伦精品一区二区三区88av| 久久一区二区三区国产精品| 999久久久国产| 亚洲一区二区三区激情| 黄色av网站免费| 91精品国产手机| 欧美69xxxxx| 欧美成人小视频| 亚洲国产福利| 1卡2卡3卡精品视频| 亚洲黄色录像| 中文字幕一区二区三区乱码| av成人激情| 中文字幕久久av| 91视频观看视频| 永久久久久久久| 日韩欧美国产一区二区| 国产男女无套免费网站| 亚洲欧美国内爽妇网| 91小视频xxxx网站在线| 国产成人精品综合| 国产精品午夜av| 杨幂一区欧美专区| 久久狠狠一本精品综合网| 韩国三级在线播放| 国产精品每日更新在线播放网址| 日本免费观看视| 欧美一区二区三区四区久久| 福利成人在线观看| 欧美亚洲国产成人精品| 91久久偷偷做嫩草影院电| 午夜久久资源| 销魂美女一区二区三区视频在线| 成人区精品一区二区| 在线观看免费中文字幕| 在线播放中文一区| 国产高清av在线| 欧美亚洲另类制服自拍| 日本99精品| 中日韩在线视频| 免费成人在线视频观看| 欧美狂猛xxxxx乱大交3| 精品久久久久国产| 亚洲毛片欧洲毛片国产一品色| 久久精品99久久香蕉国产色戒| 韩国美女久久| 久久久久久久久久久一区| 亚洲午夜一区| 无码人妻一区二区三区在线视频| 国产精品免费观看视频| 99久久久无码国产精品免费蜜柚| 亚洲成**性毛茸茸| 新版中文在线官网| 95av在线视频| 亚洲精品一二三区区别| 日韩一级理论片| 日本一区二区三级电影在线观看| 日本高清不卡码| 亚洲免费视频网站| 性欧美freesex顶级少妇| 精品视频在线观看| 在线亚洲观看| 国产精品成人无码专区| 亚洲电影一级黄| 无码精品在线观看| 91精品国产成人www| 日本成人中文| 久久久免费视频网站| 91国内外精品自在线播放| 国产91露脸中文字幕在线| 亚洲区小说区图片区qvod| 欧美亚洲另类色图| 久久色中文字幕| 精品无码一区二区三区的天堂| 亚洲精品之草原avav久久| 你懂得影院夜精品a| 亚洲高清在线播放| 麻豆91在线看| 午夜精品福利在线视频| 欧美成人性战久久| 蜜桃视频在线观看播放| 欧美日韩精品久久| 首页国产欧美日韩丝袜| 538精品视频| 日韩一区二区免费在线电影| 欧美人与性动交α欧美精品济南到 | 狼狼综合久久久久综合网| 日韩激情视频网站| 波兰性xxxxx极品hd| 日韩美女在线视频| 色在线中文字幕| 亚洲精品一区二区三| 国产精品99久久不卡二区| 日操夜操天天操| 国产亚洲激情视频在线| 中文字幕日本一区| 国产欧美精品aaaaaa片| 2014亚洲片线观看视频免费| 中文字幕在线一| 久久久久久久影院| 最新国产精品视频| 天天摸天天舔天天操| 午夜精品福利一区二区三区蜜桃| freemovies性欧美| 国产成人精品日本亚洲11| 日本欧美一区二区| 久久久久久久久久久久久久久久久| 亚洲黄色有码视频| 四虎国产精品永久在线国在线 | 超碰电影在线播放| 精品国产一区二区三区四区vr| 青青草精品视频| 精品久久久久久中文字幕2017|