You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

357 lines
13 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2020. All rights reserved.
* Description: NxMetadataRetriever class implement
* Author: NxPlayer software group
* Create: 2019-11-21
*/
#define LOG_NDEBUG 0
#define LOG_TAG "HR_RET"
#include "NxMetadataRetriever.h"
#include "NxMediaDefine.h"
#include <log/log.h>
#include <cstring>
#include <cinttypes>
#include <utils/Errors.h>
using ::android::hardware::hidl_handle;
namespace android {
NxMetadataRetriever::NxMetadataRetriever(int idx)
:m_deathRecipient(nullptr), m_instIdx(idx)
{
HLOGI("call %s in", __FUNCTION__);
m_nxMetadataStore = INxPlayerMetadataStore::getService();
if (m_nxMetadataStore.get() == nullptr) {
HLOGE("getService metadataStore failed");
}
sp<INxPlayerMetadata> p;
Return<void> transCreate = m_nxMetadataStore->createNxPlayerMetadata(
[&p, this](int32_t status, const sp<INxPlayerMetadata> &comp) {
if (status != 0) {
HLOGE("createNxMediaPlayerMetadata failed");
return;
}
p = comp;
});
m_nxMetadata = p;
InitDeathRecipient();
HLOGI("call %s out", __FUNCTION__);
}
void NxMetadataRetriever::InitDeathRecipient()
{
m_deathRecipient = new(std::nothrow) DeathRecipient(this, m_instIdx);
if (m_deathRecipient.get() == nullptr) {
HLOGE("new DeathRecipient failed");
}
if (m_deathRecipient.get() != nullptr && m_nxMetadata != nullptr) {
uint64_t cookie = reinterpret_cast<uintptr_t>(m_nxMetadata.get());
if (!m_nxMetadata->linkToDeath(m_deathRecipient, cookie)) {
HLOGE("register death notification failed");
} else {
HLOGD("register death notification success");
}
}
}
void NxMetadataRetriever::DeInitDeathRecipient()
{
if (m_deathRecipient.get() != nullptr && m_nxMetadata != nullptr) {
m_nxMetadata->unlinkToDeath(m_deathRecipient);
}
}
NxMetadataRetriever::~NxMetadataRetriever()
{
HLOGI("call %s in", __FUNCTION__);
DeInitDeathRecipient();
m_nxMetadata.clear();
HLOGI("call %s out", __FUNCTION__);
}
status_t NxMetadataRetriever::setDataSource(const char *url,
const KeyedVector<String8, String8> *headers)
{
HLOGI("call %s in, uri=*", __FUNCTION__);
hidl_string urlHidl(url);
std::vector<Header> headersTemp;
if (headers != nullptr) {
for (size_t i = 0; i < headers->size(); i++) {
Header header{headers->keyAt(i).c_str(), headers->valueAt(i).c_str()};
headersTemp.push_back(header);
}
}
hidl_vec<Header> headersHidl = headersTemp;
Return<int32_t> transSetDataSourceNetwork = m_nxMetadata->setDataSourceUrl(urlHidl, headersHidl);
if (!transSetDataSourceNetwork.isOk() || static_cast<int32_t>(transSetDataSourceNetwork) != 0) {
HLOGE("SetDataSourceNetwork failed");
return UNKNOWN_ERROR;
}
HLOGI("call %s out", __FUNCTION__);
return NO_ERROR;
}
status_t NxMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length)
{
HLOGI("call %s in", __FUNCTION__);
native_handle_t * const nativeHdl = native_handle_create(1, 0);
if (nativeHdl == nullptr) {
HLOGE("nativeHdl is null");
return UNKNOWN_ERROR;
}
nativeHdl->data[0] = fd;
hidl_handle fdHandle;
fdHandle.setTo(nativeHdl, false);
Return<int32_t> transSetDataSourceLocal = m_nxMetadata->setDataSourceFd(fdHandle, offset, length);
if (!transSetDataSourceLocal.isOk() || static_cast<int32_t>(transSetDataSourceLocal) != 0) {
HLOGE("transSetDataSourceLocal failed");
return UNKNOWN_ERROR;
}
HLOGI("call %s out", __FUNCTION__);
return NO_ERROR;
}
void NxMetadataRetriever::InitPicInfo(PIC_INFO &picInfo, const MediaBuffer &pic) const
{
HLOGD("%s", __FUNCTION__);
picInfo.picWidth = pic.width;
picInfo.picHeight = pic.height;
picInfo.picRotation = pic.rotation;
picInfo.picSize = pic.size;
picInfo.picData = pic.data;
}
void NxMetadataRetriever::CopyFrameInfo(ThumbnailInfo &outInfo, const PIC_INFO &picInfo) const
{
HLOGD("%s, rotation=%d", __FUNCTION__, picInfo.picRotation);
outInfo.width = picInfo.picWidth;
outInfo.height = picInfo.picHeight;
outInfo.rotation = picInfo.picRotation;
outInfo.picSize = picInfo.picSize;
}
sp<IMemory> NxMetadataRetriever::getFrameAtTime(int64_t timeUs, ThumbnailParam &inParam, ThumbnailInfo &outInfo)
{
HLOGI("call %s in", __FUNCTION__);
PIC_INFO picInfo = {};
Return<void> transGetFrameAtTime = m_nxMetadata->getFrameAtTime(
timeUs, inParam.option, inParam.colorFormat, inParam.metaOnly,
[&picInfo, this](int32_t ret, const MediaBuffer &pic) {
if (ret != 0) {
HLOGE("getFrameAtTime failed");
return;
}
InitPicInfo(picInfo, pic);
});
if (!transGetFrameAtTime.isOk() || (picInfo.picSize == 0)) {
HLOGE("transGetFrameAtTime failed");
return nullptr;
}
uint8_t *frameCopy = nullptr;
size_t size = inParam.extraSize + picInfo.picSize;
sp<MemoryHeapBase> heap = new MemoryHeapBase(size, 0, "NxMetadataRetriever");
if (heap.get() == nullptr) {
HLOGE("new MemoryHeapBase with size=%zu failed", size);
return nullptr;
}
sp<IMemory> thumbnail = new MemoryBase(heap, 0, size);
if (thumbnail.get() == nullptr) {
HLOGE("new MemoryBase failed, not enough memory for VideoFrame size=%zu", size);
return nullptr;
}
/* For the RGB picture, only one block (block 0) is used. In this case, pay attention only to frameData[0] */
#if (PLATFORM_SDK_VERSION >= 31)
frameCopy = static_cast<uint8_t *>(thumbnail->unsecurePointer());
#else
frameCopy = static_cast<uint8_t *>(thumbnail->pointer());
#endif
if (frameCopy == nullptr) {
HLOGE("frameCopy is null");
return nullptr;
}
sp<HMemory> memory = mapMemory(picInfo.picData);
if (memory.get() == nullptr || memory->getPointer() == nullptr) {
HLOGE("mapMemory failed");
return nullptr;
}
if (memcpy_s(frameCopy + inParam.extraSize, picInfo.picSize, memory->getPointer(), picInfo.picSize) != EOK) {
HLOGE("memcpy_s failed");
return nullptr;
}
CopyFrameInfo(outInfo, picInfo);
HLOGI("call %s out", __FUNCTION__);
return thumbnail;
}
sp<IMemory> NxMetadataRetriever::getImageAtIndex(int index, ThumbnailParam &inParam, ThumbnailInfo &outInfo)
{
HLOGI("call %s in", __FUNCTION__);
(void)outInfo;
uint32_t picWidth;
uint32_t picHeight;
uint32_t picSize;
hidl_memory picData;
Return<void> transGetImageAtIndex = m_nxMetadata->getImageAtIndex(
index, inParam.colorFormat, inParam.metaOnly, inParam.thumbnail,
[&picWidth, &picHeight, &picSize, &picData, this](int32_t ret, const MediaBuffer &pic) {
if (ret != 0) {
HLOGE("transGetImageAtIndex failed");
return;
}
picWidth = pic.width;
picHeight = pic.height;
picSize = pic.size;
picData = pic.data;
});
if (!transGetImageAtIndex.isOk()) {
HLOGE("transGetImageAtIndex failed");
return nullptr;
}
HLOGI("call %s out", __FUNCTION__);
return nullptr;
}
sp<IMemory> NxMetadataRetriever::getImageRectAtIndex(int index, ThumbnailParam &inParam,
ThumbnailRect &rectInfo, ThumbnailInfo &outInfo)
{
HLOGI("call %s in", __FUNCTION__);
(void)outInfo;
uint32_t picWidth;
uint32_t picHeight;
uint32_t picSize;
hidl_memory picData;
Return<void> transGetImageRectAtIndex = m_nxMetadata->getImageRectAtIndex(
index, inParam.colorFormat, rectInfo.left, rectInfo.top, rectInfo.right, rectInfo.bottom,
[&picWidth, &picHeight, &picSize, &picData, this](int32_t ret, const MediaBuffer &pic) {
if (ret != 0) {
HLOGE("getImageRectAtIndex failed");
return;
}
picWidth = pic.width;
picHeight = pic.height;
picSize = pic.size;
picData = pic.data;
});
if (!transGetImageRectAtIndex.isOk()) {
HLOGE("transGetImageAtIndex failed");
return nullptr;
}
HLOGI("call %s out", __FUNCTION__);
return nullptr;
}
status_t NxMetadataRetriever::getFrameAtIndex(std::vector<sp<IMemory>> *frames, int frameIndex, int numFrames,
ThumbnailParam &inParam, std::vector<ThumbnailInfo> &outInfo)
{
HLOGI("call %s in", __FUNCTION__);
(void)outInfo;
Return<void> transGetFrameAtIndex = m_nxMetadata->getFrameAtIndex(
frameIndex, numFrames, inParam.colorFormat, inParam.metaOnly,
[this](int32_t ret, const hidl_vec<MediaBuffer> &pic) {
if (ret != 0) {
HLOGE("getFrameAtIndex failed");
return;
}
(void)pic;
});
if (!transGetFrameAtIndex.isOk()) {
HLOGE("transGetImageAtIndex failed");
return UNKNOWN_ERROR;
}
HLOGE("call %s out, not support getFrameAtIndex", __FUNCTION__);
return UNKNOWN_ERROR;
}
sp<IMemory> NxMetadataRetriever::getFrameAtIndex(int frameIndex, ThumbnailParam &inParam,
ThumbnailInfo &outInfo)
{
HLOGI("call %s in", __FUNCTION__);
(void)outInfo;
HLOGE("call %s out, not support getFrameAtIndex! frameIndex:%d, colorFormat:%d,metaOnly:%d", __FUNCTION__,
frameIndex, inParam.colorFormat, inParam.metaOnly);
return nullptr;
}
const char *NxMetadataRetriever::extractMetadata(int keyCode)
{
HLOGI("call %s in", __FUNCTION__);
hidl_string metaData;
Return<void> transExtractMetadata = m_nxMetadata->extractMetadata(
keyCode,
[&metaData, this](int32_t ret, const hidl_string &metadata) {
if (ret != 0) {
HLOGE("extractMetadata failed");
return;
}
metaData = metadata;
});
if (!transExtractMetadata.isOk()) {
HLOGE("transExtractMetadata failed");
return nullptr;
}
HLOGI("call %s out", __FUNCTION__);
if (!metaData.empty()) {
return strdup(metaData.c_str());
} else {
return nullptr;
}
}
std::string NxMetadataRetriever::extractAlbumArt()
{
HLOGI("call %s in", __FUNCTION__);
std::string albumArtStr;
Return<void> transExtractAlbumArt = m_nxMetadata->extractAlbumArt(
[&albumArtStr, this](int32_t ret, const hidl_string &albumArtString) {
if (ret != 0) {
HLOGE("extractAlbumArt failed");
return;
}
albumArtStr = albumArtString;
});
if (!transExtractAlbumArt.isOk()) {
HLOGE("transExtractMetadata failed");
return albumArtStr;
}
HLOGI("call %s out", __FUNCTION__);
return albumArtStr;
}
void NxMetadataRetriever::DeathRecipient::serviceDied(uint64_t cookie,
const wp< ::android::hidl::base::V1_0::IBase > &) /* who */
{
/* handle death notify */
HLOGE("call %s, player cookie=%" PRIu64 "", __FUNCTION__, cookie);
if (m_nxMetadataRetriever != nullptr) {
m_nxMetadataRetriever->m_nxMetadata.clear();
}
}
NxMetadataRetriever::DeathRecipient::~DeathRecipient()
{
HLOGD("release %s", __FUNCTION__);
}
extern "C" android::NxMetadataRetrieverInterface *CreateNxMetadataRetrieverInterfaceInstance(int idx)
{
ALOGI("[%d][%s:%d]: create %s", idx, __FUNCTION__, __LINE__, __FUNCTION__);
return new ::android::NxMetadataRetriever(idx);
}
extern "C" void DestroyNxMetadataRetrieverInterfaceInstance(
android::NxMetadataRetrieverInterface *metadataRetriever, int idx)
{
ALOGI("[%d][%s:%d]: delete %s", idx, __FUNCTION__, __LINE__, __FUNCTION__);
delete metadataRetriever;
}
};