国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

使用 MediaCodec 在 Android 上進行硬解碼

這篇具有很好參考價值的文章主要介紹了使用 MediaCodec 在 Android 上進行硬解碼。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

要使用 MediaCodec 在 Android 上進行硬解碼,并獲取 RGBA 數(shù)據(jù),你可以按照以下步驟進行操作:

創(chuàng)建 MediaExtractor 對象并設(shè)置要解碼的 MP4 文件路徑:

MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(filePath);

根據(jù)需要選擇音頻或視頻軌道:

int trackCount = extractor.getTrackCount();
int trackIndex = -1;
for (int i = 0; i < trackCount; i++) {
    MediaFormat format = extractor.getTrackFormat(i);
    String mime = format.getString(MediaFormat.KEY_MIME);
    if (mime.startsWith("video/")) {
        trackIndex = i;
        break;
    }
}
if (trackIndex >= 0) {
    extractor.selectTrack(trackIndex);
}

創(chuàng)建 MediaCodec 對象并配置解碼器:

MediaFormat format = extractor.getTrackFormat(trackIndex);
String mime = format.getString(MediaFormat.KEY_MIME);
MediaCodec codec = MediaCodec.createDecoderByType(mime);
codec.configure(format, null, null, 0);
codec.start();

循環(huán)解碼并獲取 RGBA 數(shù)據(jù):

MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
boolean isEOS = false;
while (!isEOS) {
    int inputBufferIndex = codec.dequeueInputBuffer(timeoutUs);
    if (inputBufferIndex >= 0) {
        ByteBuffer inputBuffer = codec.getInputBuffer(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 {
            long presentationTimeUs = extractor.getSampleTime();
            codec.queueInputBuffer(inputBufferIndex, 0, sampleSize, presentationTimeUs, 0);
            extractor.advance();
        }
    }

    int outputBufferIndex = codec.dequeueOutputBuffer(bufferInfo, timeoutUs);
    if (outputBufferIndex >= 0) {
        ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferIndex);
        // 解碼后的數(shù)據(jù)位于 outputBuffer 中,根據(jù)需要進行 RGBA 數(shù)據(jù)的提取和處理
        // outputBuffer 中的數(shù)據(jù)格式可能是 YUV 或其他格式,需要根據(jù)解碼器設(shè)置的輸出格式進行相應(yīng)的轉(zhuǎn)換
        codec.releaseOutputBuffer(outputBufferIndex, false);
    } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
        // 解碼器輸出格式已更改,可以通過 codec.getOutputFormat() 獲取新的格式
    }
}

在上述代碼中,你需要根據(jù)解碼器輸出的數(shù)據(jù)格式進行相應(yīng)的轉(zhuǎn)換,以獲取 RGBA 數(shù)據(jù)。具體的轉(zhuǎn)換流程和代碼取決于解碼器輸出的數(shù)據(jù)格式和你的需求。

需要注意的是,硬解碼的支持和性能可能因設(shè)備、Android 版本和視頻編碼格式的不同而有所差異。確保你的設(shè)備支持硬解碼,并且適當(dāng)處理解碼器的輸入和輸出緩沖區(qū)。

以下是完整代碼:文章來源地址http://www.zghlxwxcb.cn/news/detail-856671.html

import android.media.MediaCodec;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.util.Log;

import java.nio.ByteBuffer;

public class MP4Decoder {
    private static final int TIMEOUT_US = 10000;
    private static final String TAG = "MP4Decoder";

    public interface FrameCallback {
        void onFrameDecoded(byte[] rgbaData, int width, int height);
    }

    public static void decodeMP4(String filePath, FrameCallback callback) {
        new Thread(() -> {
            MediaExtractor extractor = new MediaExtractor();
            try {
                extractor.setDataSource(filePath);

                int trackIndex = selectVideoTrack(extractor);
                if (trackIndex < 0) {
                    return;
                }

                MediaFormat format = extractor.getTrackFormat(trackIndex);
                String mime = format.getString(MediaFormat.KEY_MIME);
                MediaCodec codec = MediaCodec.createDecoderByType(mime);
                codec.configure(format, null, null, 0);
                codec.start();

                MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
                boolean isEOS = false;
                while (!isEOS) {
                    int inputBufferIndex = codec.dequeueInputBuffer(TIMEOUT_US);
                    if (inputBufferIndex >= 0) {
                        ByteBuffer inputBuffer = codec.getInputBuffer(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 {
                            long presentationTimeUs = extractor.getSampleTime();
                            codec.queueInputBuffer(inputBufferIndex, 0, sampleSize, presentationTimeUs, 0);
                            extractor.advance();
                        }
                    }

                    int outputBufferIndex = codec.dequeueOutputBuffer(bufferInfo, TIMEOUT_US);
                    if (outputBufferIndex >= 0) {
                        ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferIndex);
                        // 解碼后的數(shù)據(jù)位于 outputBuffer 中,根據(jù)需要進行 RGBA 數(shù)據(jù)的提取和處理
                        // outputBuffer 中的數(shù)據(jù)格式可能是 YUV 或其他格式,需要根據(jù)解碼器設(shè)置的輸出格式進行相應(yīng)的轉(zhuǎn)換
                        byte[] rgbaData = convertToRGBA(outputBuffer, format);
                        int width = format.getInteger(MediaFormat.KEY_WIDTH);
                        int height = format.getInteger(MediaFormat.KEY_HEIGHT);
                        callback.onFrameDecoded(rgbaData, width, height);
                        codec.releaseOutputBuffer(outputBufferIndex, false);
                    } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                        // 解碼器輸出格式已更改,可以通過 codec.getOutputFormat() 獲取新的格式
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                extractor.release();
            }
        }).start();
    }

    private static int selectVideoTrack(MediaExtractor extractor) {
        int trackCount = extractor.getTrackCount();
        int trackIndex = -1;
        for (int i = 0; i < trackCount; i++) {
            MediaFormat format = extractor.getTrackFormat(i);
            String mime = format.getString(MediaFormat.KEY_MIME);
            if (mime.startsWith("video/")) {
                trackIndex = i;
                break;
            }
        }
        if (trackIndex >= 0) {
            extractor.selectTrack(trackIndex);
        }
        return trackIndex;
    }

    private static byte[] convertToRGBA(ByteBuffer buffer, MediaFormat format) {
        // 根據(jù)解碼器設(shè)置的輸出格式進行 RGBA 數(shù)據(jù)的提取和處理
        // 這里只是一個示例,實際的轉(zhuǎn)換過程可能會更復(fù)雜,取決于輸出格式和需求
        int width = format.getInteger(MediaFormat.KEY_WIDTH);
        int height = format.getInteger(MediaFormat.KEY_HEIGHT);
        int remaining = buffer.remaining();
        byte[] rgbaData = new byte[remaining];
        buffer.rewind();
        buffer.get(rgbaData);
        Log.i(TAG, "convertToRGBA: count:" + width + "; " + height + "; " + remaining);
        // todo: 進行 YUV 到 RGBA 的轉(zhuǎn)換
        return rgbaData;
    }
}

到了這里,關(guān)于使用 MediaCodec 在 Android 上進行硬解碼的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【學(xué)習(xí)】從零開發(fā)的Android音視頻開發(fā)(13)——MediaCodec到OMX框架過程及其硬解碼

    【學(xué)習(xí)】從零開發(fā)的Android音視頻開發(fā)(13)——MediaCodec到OMX框架過程及其硬解碼

    在講NuPlayer時,NuPlayer解碼部分會創(chuàng)建MediaCodec,并且最終到達OMX框架,先看MediaCodec的 init 函數(shù) 從init函數(shù)中可以看到,首先創(chuàng)建了 ACodec ,并且初始化了 ALooper 、 AMessage ,由于ACodec繼承自 AHandler ,那么一套消息機制就有了。最后發(fā)送 kWhatInit 消息,收到消息的邏輯位于ACodec.

    2023年04月08日
    瀏覽(32)
  • Android MediaCodec將h264實時視頻流數(shù)據(jù)解碼為yuv,并轉(zhuǎn)換yuv的顏色格式為nv21

    初始化mediacodec 處理數(shù)據(jù),解碼h264數(shù)據(jù)為yuv格式 這里傳入的是h264格式的實時視頻流數(shù)據(jù)。 處理獲取到的nv21顏色格式的yuv數(shù)據(jù) ?yuv視頻數(shù)據(jù)顏色格式轉(zhuǎn)換 h264實時視頻流的數(shù)據(jù)來源 寫入h264視頻流到sdcard中 rtsp獲取h264實時視頻流數(shù)據(jù) ?編寫C代碼加載ffmpeg庫 源碼地址 https://gi

    2024年01月17日
    瀏覽(30)
  • MediaCodec 低延時解碼

    我們在使用Android的硬解進行解碼時,如果是Android11以上則可以使用其特性低延遲,谷歌官方文檔 以下是Android 11支持的低時延特性: ANGLE支持:Android 11引入了ANGLE(Almost Native Graphics Layer Engine)支持,它是一個開源的跨平臺圖形引擎,可以將OpenGL ES和Vulkan API轉(zhuǎn)換為DirectX API。

    2024年02月14日
    瀏覽(16)
  • 王學(xué)崗視頻編碼————視頻編解碼基礎(chǔ)與MediaCodec編解碼(對應(yīng)1234節(jié))

    王學(xué)崗視頻編碼————視頻編解碼基礎(chǔ)與MediaCodec編解碼(對應(yīng)1234節(jié))

    核心競爭力,高端人才相當(dāng)缺乏,技術(shù)迭代慢, 資料比較少,音視頻最難的地方在于編碼,沒有形成完整的體系 1,視頻文件:MP4,RMVB, AVI,F(xiàn)LV 2,現(xiàn)在學(xué)音視頻和以前的區(qū)別, 以前:播放本地文件, 現(xiàn)在:播放網(wǎng)絡(luò)流(視頻流和音頻流) 3,RMVB、MP4等是封裝格式,是一個容

    2023年04月08日
    瀏覽(21)
  • Android MediaCodec 簡明教程(五):使用 MediaCodec 編碼 ByteBuffer 數(shù)據(jù),并保存為 MP4 文件

    Android MediaCodec 簡明教程(五):使用 MediaCodec 編碼 ByteBuffer 數(shù)據(jù),并保存為 MP4 文件

    Android MediaCodec 簡明教程(一):使用 MediaCodecList 查詢 Codec 信息,并創(chuàng)建 MediaCodec 編解碼器 Android MediaCodec 簡明教程(二):使用 MediaCodecInfo.CodecCapabilities 查詢 Codec 支持的寬高,顏色空間等能力 Android MediaCodec 簡明教程(三):詳解如何在同步與異步模式下,使用MediaCodec將視

    2024年04月13日
    瀏覽(57)
  • Android MediaCodec解析

    Android MediaCodec解析

    MediaCodec是Android平臺提供的一個底層的音視頻編解碼框架,它是安卓底層多媒體基礎(chǔ)框架的重要組成部分。它經(jīng)常和 MediaExtractor, MediaSync, MediaMuxer, MediaCrypto, MediaDrm, Image, Surface, AudioTrack 一起使用。 解碼 的作用,就是將視頻/音頻壓縮編碼數(shù)據(jù),解碼成為非壓縮的視頻/音頻原始

    2024年02月15日
    瀏覽(26)
  • Android音視頻-MediaCodec

    Android音視頻-MediaCodec

    原文:https://mp.weixin.qq.com/s?__biz=MzU3NTA3MDU1OQ==mid=2247484865idx=1sn=174b8ca702466e83e72c7115d91b06eachksm=fd298df1ca5e04e7b2df9dc9f21e5cfe3e910204c905d8605f648ce6f6404432a83ae52a23a3scene=178cur_album_id=1638784435628064770#rd MediaCodec 支持處理三種數(shù)據(jù)類型,分別是壓縮數(shù)據(jù)(compressed data)、原始音頻數(shù)據(jù)(raw audio d

    2023年04月08日
    瀏覽(17)
  • Android MediaCodec 框架 基于codec2

    Android MediaCodec 框架 基于codec2

    系列文章的目的是什么? 粗略: 解碼需要哪些基礎(chǔ)的服務(wù)? 標(biāo)準(zhǔn)解碼的調(diào)用流程? 各個流程的作用是什么? 解碼框架的層次? 各個層次的作用? 細(xì)化: 解碼參數(shù)的配置? 解碼輸入數(shù)據(jù)包的流轉(zhuǎn)? 解碼輸出幀內(nèi)存的申請和管理? 首先從MediaCodec 到具體的解碼Component 梳理出

    2024年02月07日
    瀏覽(21)
  • Android之MediaCodec::PostAndAwaitResponse消息原理(四十三)

    Android之MediaCodec::PostAndAwaitResponse消息原理(四十三)

    簡介: CSDN博客專家,專注Android/Linux系統(tǒng),分享多mic語音方案、音視頻、編解碼等技術(shù),與大家一起成長! 優(yōu)質(zhì)專欄: Audio工程師進階系列 【 原創(chuàng)干貨持續(xù)更新中…… 】?? 人生格言: 人生從來沒有捷徑,只有行動才是治療恐懼和懶惰的唯一良藥. 更多原創(chuàng),歡迎關(guān)注:An

    2024年02月07日
    瀏覽(14)
  • [Android] 如何編寫基于MediaCodec的播放器

    基于MediaCodec JNI的播放器,以 native mediacodec demo 為基礎(chǔ)擴展

    2024年02月12日
    瀏覽(15)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包