Android判断是否使用MediaCodec硬解码(十二)

本文主要介绍如何在Android系统中检测是否使用MediaCodec进行硬解码。作者作为CSDN博客专家,专注于Android/Linux领域的音视频、编解码技术,分享了判断MediaCodec硬解码的相关技术细节,帮助开发者提升应用性能。
摘要由CSDN通过智能技术生成

 简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀

人生格言:

以下是使用C++ MediaCodec 进行视频解码的示例代码: ```c++ #include <jni.h> #include <android/log.h> #include <android/native_window_jni.h> #include <media/NdkMediaCodec.h> #include <media/NdkMediaExtractor.h> #define LOG_TAG "MediaCodec" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) extern "C" JNIEXPORT void JNICALL Java_com_example_mediadecoder_MainActivity_decode(JNIEnv *env, jobject thiz, jstring filePath, jobject surface) { const char *path = env->GetStringUTFChars(filePath, nullptr); AMediaExtractor *extractor = AMediaExtractor_new(); AMediaCodec *codec = nullptr; int32_t trackIndex = -1; bool sawInputEOS = false; bool sawOutputEOS = false; // 设置文件路径 media_status_t result = AMediaExtractor_setDataSource(extractor, path); if (result != AMEDIA_OK) { LOGE("AMediaExtractor_setDataSource error: %d", result); goto end; } // 查找视频轨道 int32_t numTracks = AMediaExtractor_getTrackCount(extractor); for (int32_t i = 0; i < numTracks; ++i) { AMediaFormat *format = AMediaExtractor_getTrackFormat(extractor, i); const char *mime = nullptr; AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime); if (mime && !strncmp(mime, "video/", 6)) { trackIndex = i; break; } AMediaFormat_delete(format); } if (trackIndex == -1) { LOGE("No video track found in %s", path); goto end; } // 获取视频格式 AMediaFormat *format = AMediaExtractor_getTrackFormat(extractor, trackIndex); int32_t width = 0, height = 0; AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_WIDTH, &width); AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_HEIGHT, &height); LOGI("Video size: %dx%d", width, height); // 创建 MediaCodec 解码器 codec = AMediaCodec_createDecoderByType("video/avc"); result = AMediaCodec_configure(codec, format, ANativeWindow_fromSurface(env, surface), nullptr, 0); if (result != AMEDIA_OK) { LOGE("AMediaCodec_configure error: %d", result); goto end; } // 启动解码器 result = AMediaCodec_start(codec); if (result != AMEDIA_OK) { LOGE("AMediaCodec_start error: %d", result); goto end; } // 解码视频帧 AMediaCodecBufferInfo bufferInfo; int64_t presentationTimeUs; size_t bufIdx; while (!sawOutputEOS) { if (!sawInputEOS) { bufIdx = AMediaExtractor_getSampleTrackIndex(extractor); if (bufIdx == trackIndex) { result = AMediaExtractor_readSampleData(extractor, AMediaCodec_getInputBuffer(codec, bufIdx), 0); if (result == AMEDIA_OK) { presentationTimeUs = AMediaExtractor_getSampleTime(extractor); AMediaCodec_queueInputBuffer(codec, bufIdx, 0, AMediaExtractor_getSampleSize(extractor), presentationTimeUs, AMediaExtractor_getSampleFlags(extractor)); AMediaExtractor_advance(extractor); } else if (result == AMEDIA_ERROR_END_OF_STREAM) { sawInputEOS = true; AMediaCodec_queueInputBuffer(codec, bufIdx, 0, 0, 0, AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM); } else { LOGE("AMediaExtractor_readSampleData error: %d", result); goto end; } } } result = AMediaCodec_dequeueOutputBuffer(codec, &bufferInfo, 5000); if (result == AMEDIA_OK) { if (bufferInfo.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) { sawOutputEOS = true; } AMediaCodec_releaseOutputBuffer(codec, result, true); } else if (result == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) { AMediaFormat *newFormat = nullptr; newFormat = AMediaCodec_getOutputFormat(codec); AMediaFormat_getInt32(newFormat, AMEDIAFORMAT_KEY_WIDTH, &width); AMediaFormat_getInt32(newFormat, AMEDIAFORMAT_KEY_HEIGHT, &height); LOGI("Video output format changed to %dx%d", width, height); AMediaFormat_delete(newFormat); } else if (result == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) { LOGI("AMediaCodec_dequeueOutputBuffer returned AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED"); } else { LOGE("AMediaCodec_dequeueOutputBuffer error: %d", result); goto end; } } end: if (codec) { AMediaCodec_stop(codec); AMediaCodec_delete(codec); } if (extractor) { AMediaExtractor_delete(extractor); } env->ReleaseStringUTFChars(filePath, path); } ``` 在此示例代码中,我们使用 `AMediaExtractor` 获取视频文件中的视频轨道,并使用 `AMediaCodec` 进行解码。注意,此代码仅支持解码 H.264 编码视频。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Android系统攻城狮

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值