131 lines
4.4 KiB
C++
131 lines
4.4 KiB
C++
#define LOG_TAG "MediaCodecWrapper"
|
|
#include <media/stagefright/MediaCodecList.h>
|
|
#include "MediaCodecWrapper.h"
|
|
|
|
using android::sp;
|
|
using android::AMessage;
|
|
using android::Vector;
|
|
using android::AString;
|
|
using android::MediaCodecList;
|
|
|
|
namespace aml_mp {
|
|
|
|
static const char *MEDIA_MIMETYPE_VIDEO_AVC = "video/avc";
|
|
static const char *MEDIA_MIMETYPE_VIDEO_AVS = "video/avs";
|
|
static const char *MEDIA_MIMETYPE_VIDEO_HEVC = "video/hevc";
|
|
static const char *MEDIA_MIMETYPE_VIDEO_VP9 = "video/x-vnd.on2.vp9";
|
|
//static const char *MEDIA_MIMETYPE_VIDEO_DOLBY_VISION = "video/dolby-vision";
|
|
//static const char *MEDIA_MIMETYPE_VIDEO_MPEG = "video/mpeg";
|
|
static const char *MEDIA_MIMETYPE_VIDEO_MPEG2 = "video/mpeg2";
|
|
static const char *MEDIA_MIMETYPE_VIDEO_MPEG4 = "video/mp4v-es";
|
|
static const char *MEDIA_MIMETYPE_VIDEO_MJPEG = "video/mjpeg";
|
|
|
|
static const char * convertCodecIdToMimeType(Aml_MP_CodecID aml_MP_VideoCodec) {
|
|
switch (aml_MP_VideoCodec) {
|
|
case AML_MP_VIDEO_CODEC_MPEG12:
|
|
return MEDIA_MIMETYPE_VIDEO_MPEG2;
|
|
case AML_MP_VIDEO_CODEC_MPEG4:
|
|
return MEDIA_MIMETYPE_VIDEO_MPEG4;
|
|
case AML_MP_VIDEO_CODEC_MJPEG:
|
|
return MEDIA_MIMETYPE_VIDEO_MJPEG;
|
|
case AML_MP_VIDEO_CODEC_H264:
|
|
return MEDIA_MIMETYPE_VIDEO_AVC;
|
|
case AML_MP_VIDEO_CODEC_AVS:
|
|
return MEDIA_MIMETYPE_VIDEO_AVS;
|
|
case AML_MP_VIDEO_CODEC_VP9:
|
|
return MEDIA_MIMETYPE_VIDEO_VP9;
|
|
case AML_MP_VIDEO_CODEC_HEVC:
|
|
return MEDIA_MIMETYPE_VIDEO_HEVC;
|
|
default:
|
|
break;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
MediaCodecWrapper::MediaCodecWrapper() {
|
|
snprintf(mName, sizeof(mName), "%s", LOG_TAG);
|
|
memset(&mMediaCodecParams, 0, sizeof(mMediaCodecParams));
|
|
}
|
|
|
|
MediaCodecWrapper::~MediaCodecWrapper() {
|
|
release();
|
|
}
|
|
|
|
void MediaCodecWrapper::configure(MediaCodecParams mediaCodecParams) {
|
|
mMediaCodecParams = mediaCodecParams;
|
|
// find mediacodec list, prefer the omx.amlogic decoder
|
|
Vector<AString> matchingCodecs;
|
|
matchingCodecs.clear();
|
|
size_t index = 0;
|
|
const char* mime = convertCodecIdToMimeType(mediaCodecParams.codecId);
|
|
MediaCodecList::findMatchingCodecs(mime, false, MediaCodecList::Flags::kHardwareCodecsOnly, &matchingCodecs);
|
|
//coverity[uninit_use_in_call]
|
|
for (index = 0; index < matchingCodecs.size(); index++) {
|
|
//coverity[uninit_use_in_call]
|
|
if (matchingCodecs[index].startsWithIgnoreCase("omx.amlogic")) {
|
|
break;
|
|
}
|
|
}
|
|
if (index == matchingCodecs.size()) {
|
|
MLOGI("findMatchingCodecs: there is no omx.amlogic decoder");
|
|
index = 0;
|
|
}
|
|
|
|
// Check if matchingCodecs is empty to avoid accessing invalid index
|
|
if (matchingCodecs.empty()) {
|
|
MLOGE("findMatchingCodecs: no matching codecs found for mime type %s", mime);
|
|
return;
|
|
}
|
|
|
|
const char * codecName = matchingCodecs[index].c_str();
|
|
MLOGI("AMediaCodec_createCodecByName: %s", codecName);
|
|
mCodec = AMediaCodec_createCodecByName(codecName);
|
|
sp<AMessage> format = new AMessage;
|
|
format->setString("mime", mime);
|
|
format->setInt32("width", 1920);
|
|
format->setInt32("height", 1080);
|
|
format->setInt32("audio-hw-sync", mediaCodecParams.audioHwSync);
|
|
format->setInt32("vendor.tunerhal.video-filter-id", mediaCodecParams.filterId);
|
|
format->setInt32("vendor.tunerhal.hw-av-sync-id", mediaCodecParams.hwAvSyncId);
|
|
format->setInt32("feature-tunneled-playback", 1);
|
|
|
|
// Create AMediaFormat from AMessage
|
|
// Note: AMediaFormat_fromMsg creates a new AMediaFormat object that needs to be managed
|
|
// The original AMessage (format) will be automatically cleaned up by sp<AMessage>
|
|
mFormat = AMediaFormat_fromMsg(&format);
|
|
AMediaCodec_configure(mCodec, mFormat, mediaCodecParams.nativewindow, nullptr, 0);
|
|
//coverity[leaked_storage]
|
|
}
|
|
|
|
void MediaCodecWrapper::start() {
|
|
AMediaCodec_start(mCodec);
|
|
}
|
|
|
|
size_t MediaCodecWrapper::writeData(const uint8_t *data, size_t size) {
|
|
AML_MP_UNUSED(data);
|
|
// for passthrough writeData is not necessary
|
|
return size;
|
|
}
|
|
|
|
void MediaCodecWrapper::flush() {
|
|
AMediaCodec_flush(mCodec);
|
|
}
|
|
|
|
void MediaCodecWrapper::stop() {
|
|
AMediaCodec_stop(mCodec);
|
|
}
|
|
|
|
void MediaCodecWrapper::release() {
|
|
if (mCodec) {
|
|
AMediaCodec_delete(mCodec);
|
|
mCodec = nullptr;
|
|
}
|
|
if (mFormat) {
|
|
AMediaFormat_clear(mFormat);
|
|
AMediaFormat_delete(mFormat);
|
|
mFormat = nullptr;
|
|
}
|
|
}
|
|
|
|
} // namespace aml_mp
|