aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp82
-rw-r--r--system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.h5
-rw-r--r--system/codecs/c2/decoders/avcdec/MediaH264Decoder.cpp30
-rw-r--r--system/codecs/c2/decoders/avcdec/MediaH264Decoder.h11
-rw-r--r--system/codecs/c2/decoders/base/include/goldfish_media_utils.h10
-rw-r--r--system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.cpp53
-rw-r--r--system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.h4
-rw-r--r--system/codecs/c2/decoders/hevcdec/GoldfishHevcHelper.cpp6
-rw-r--r--system/codecs/c2/decoders/hevcdec/GoldfishHevcHelper.h6
-rw-r--r--system/codecs/c2/decoders/hevcdec/MediaHevcDecoder.cpp16
-rw-r--r--system/codecs/c2/decoders/hevcdec/MediaHevcDecoder.h5
-rw-r--r--system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.cpp32
-rw-r--r--system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.h4
-rw-r--r--system/codecs/c2/decoders/vpxdec/goldfish_vpx_defs.h2
-rw-r--r--system/codecs/c2/decoders/vpxdec/goldfish_vpx_impl.cpp11
-rw-r--r--system/hwc2/DisplayFinder.cpp2
-rw-r--r--system/hwc2/HostComposer.cpp2
-rw-r--r--system/hwc3/HostFrameComposer.cpp2
-rw-r--r--system/vulkan_enc/ResourceTracker.cpp69
-rw-r--r--system/vulkan_enc/ResourceTracker.h10
-rw-r--r--system/vulkan_enc/func_table.cpp3
21 files changed, 339 insertions, 26 deletions
diff --git a/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp b/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp
index 90b56532..cbc70690 100644
--- a/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp
+++ b/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp
@@ -42,6 +42,8 @@
#include "C2GoldfishAvcDec.h"
+#include <mutex>
+
#define DEBUG 0
#if DEBUG
#define DDD(...) ALOGD(__VA_ARGS__)
@@ -64,6 +66,35 @@ constexpr uint32_t kDefaultOutputDelay = 8;
So total maximum output delay is 34 */
constexpr uint32_t kMaxOutputDelay = 34;
constexpr uint32_t kMinInputBytes = 4;
+
+static std::mutex s_decoder_count_mutex;
+static int s_decoder_count = 0;
+
+int allocateDecoderId() {
+ DDD("calling %s", __func__);
+ std::lock_guard<std::mutex> lock(s_decoder_count_mutex);
+ if (s_decoder_count >= 32 || s_decoder_count < 0) {
+ ALOGE("calling %s failed", __func__);
+ return -1;
+ }
+ ++ s_decoder_count;
+ DDD("calling %s success total decoder %d", __func__, s_decoder_count);
+ return s_decoder_count;;
+}
+
+bool deAllocateDecoderId() {
+ DDD("calling %s", __func__);
+ std::lock_guard<std::mutex> lock(s_decoder_count_mutex);
+ if (s_decoder_count < 1) {
+ ALOGE("calling %s failed ", __func__);
+ return false;
+ }
+ -- s_decoder_count;
+ DDD("calling %s success total decoder %d", __func__, s_decoder_count);
+ return true;
+}
+
+
} // namespace
class C2GoldfishAvcDec::IntfImpl : public SimpleInterface<void>::BaseParams {
@@ -307,6 +338,8 @@ class C2GoldfishAvcDec::IntfImpl : public SimpleInterface<void>::BaseParams {
if (me.v.matrix > C2Color::MATRIX_OTHER) {
me.set().matrix = C2Color::MATRIX_OTHER;
}
+ DDD("default primaries %d default range %d", me.set().primaries,
+ me.set().range);
return C2R::Ok();
}
@@ -326,6 +359,8 @@ class C2GoldfishAvcDec::IntfImpl : public SimpleInterface<void>::BaseParams {
if (me.v.matrix > C2Color::MATRIX_OTHER) {
me.set().matrix = C2Color::MATRIX_OTHER;
}
+ DDD("coded primaries %d coded range %d", me.set().primaries,
+ me.set().range);
return C2R::Ok();
}
@@ -336,6 +371,7 @@ class C2GoldfishAvcDec::IntfImpl : public SimpleInterface<void>::BaseParams {
(void)mayBlock;
// take default values for all unspecified fields, and coded values for
// specified ones
+ DDD("before change primaries %d range %d", me.v.primaries, me.v.range);
me.set().range =
coded.v.range == RANGE_UNSPECIFIED ? def.v.range : coded.v.range;
me.set().primaries = coded.v.primaries == PRIMARIES_UNSPECIFIED
@@ -346,6 +382,8 @@ class C2GoldfishAvcDec::IntfImpl : public SimpleInterface<void>::BaseParams {
: coded.v.transfer;
me.set().matrix = coded.v.matrix == MATRIX_UNSPECIFIED ? def.v.matrix
: coded.v.matrix;
+
+ DDD("after change primaries %d range %d", me.v.primaries, me.v.range);
return C2R::Ok();
}
@@ -357,7 +395,13 @@ class C2GoldfishAvcDec::IntfImpl : public SimpleInterface<void>::BaseParams {
int height() const { return mSize->height; }
- private:
+ int primaries() const { return mColorAspects->primaries; }
+
+ int range() const { return mColorAspects->range; }
+
+ int transfer() const { return mColorAspects->transfer; }
+
+ private:
std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
std::shared_ptr<C2StreamMaxPictureSizeTuning::output> mMaxSize;
@@ -393,6 +437,9 @@ C2GoldfishAvcDec::C2GoldfishAvcDec(const char *name, c2_node_id_t id,
C2GoldfishAvcDec::~C2GoldfishAvcDec() { onRelease(); }
c2_status_t C2GoldfishAvcDec::onInit() {
+ ALOGD("calling onInit");
+ mId = allocateDecoderId();
+ if (mId <= 0) return C2_NO_MEMORY;
status_t err = initDecoder();
return err == OK ? C2_OK : C2_CORRUPTED;
}
@@ -407,6 +454,11 @@ c2_status_t C2GoldfishAvcDec::onStop() {
void C2GoldfishAvcDec::onReset() { (void)onStop(); }
void C2GoldfishAvcDec::onRelease() {
+ DDD("calling onRelease");
+ if (mId > 0) {
+ deAllocateDecoderId();
+ mId = -1;
+ }
deleteContext();
if (mOutBlock) {
mOutBlock.reset();
@@ -457,6 +509,30 @@ c2_status_t C2GoldfishAvcDec::onFlush_sm() {
return C2_OK;
}
+void C2GoldfishAvcDec::sendMetadata() {
+ // compare and send if changed
+ MetaDataColorAspects currentMetaData = {1, 0, 0, 0};
+ currentMetaData.primaries = mIntf->primaries();
+ currentMetaData.range = mIntf->range();
+ currentMetaData.transfer = mIntf->transfer();
+
+ DDD("metadata primaries %d range %d transfer %d",
+ (int)(currentMetaData.primaries),
+ (int)(currentMetaData.range),
+ (int)(currentMetaData.transfer)
+ );
+
+ if (mSentMetadata.primaries == currentMetaData.primaries &&
+ mSentMetadata.range == currentMetaData.range &&
+ mSentMetadata.transfer == currentMetaData.transfer) {
+ DDD("metadata is the same, no need to update");
+ return;
+ }
+ std::swap(mSentMetadata, currentMetaData);
+
+ mContext->sendMetadata(&(mSentMetadata));
+}
+
status_t C2GoldfishAvcDec::createDecoder() {
DDD("creating avc context now w %d h %d", mWidth, mHeight);
@@ -476,7 +552,6 @@ status_t C2GoldfishAvcDec::setParams(size_t stride) {
}
status_t C2GoldfishAvcDec::initDecoder() {
- // if (OK != createDecoder()) return UNKNOWN_ERROR;
mStride = ALIGN2(mWidth);
mSignalledError = false;
resetPlugin();
@@ -682,7 +757,6 @@ void C2GoldfishAvcDec::checkMode(const std::shared_ptr<C2BlockPool> &pool) {
}
void C2GoldfishAvcDec::getVuiParams(h264_image_t &img) {
-
VuiColorAspects vuiColorAspects;
vuiColorAspects.primaries = img.color_primaries;
vuiColorAspects.transfer = img.color_trc;
@@ -931,6 +1005,8 @@ void C2GoldfishAvcDec::process(const std::unique_ptr<C2Work> &work,
} // end of whChanged
} // end of isSpsFrame
+ sendMetadata();
+
uint32_t delay;
GETTIME(&mTimeStart, nullptr);
TIME_DIFF(mTimeEnd, mTimeStart, delay);
diff --git a/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.h b/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.h
index afa27f56..d90b11a1 100644
--- a/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.h
+++ b/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.h
@@ -142,6 +142,10 @@ class C2GoldfishAvcDec : public SimpleC2Component {
}
} mBitstreamColorAspects;
+ MetaDataColorAspects mSentMetadata = {1, 0, 0, 0};
+
+ void sendMetadata();
+
// profile
struct timeval mTimeStart;
struct timeval mTimeEnd;
@@ -155,6 +159,7 @@ class C2GoldfishAvcDec : public SimpleC2Component {
std::unique_ptr<GoldfishH264Helper> mH264Helper;
+ int mId = -1;
C2_DO_NOT_COPY(C2GoldfishAvcDec);
};
diff --git a/system/codecs/c2/decoders/avcdec/MediaH264Decoder.cpp b/system/codecs/c2/decoders/avcdec/MediaH264Decoder.cpp
index 7909aa90..65607722 100644
--- a/system/codecs/c2/decoders/avcdec/MediaH264Decoder.cpp
+++ b/system/codecs/c2/decoders/avcdec/MediaH264Decoder.cpp
@@ -49,7 +49,7 @@ void MediaH264Decoder::initH264Context(unsigned int width, unsigned int height,
}
mSlot = slot;
mAddressOffSet = static_cast<unsigned int>(mSlot) * (1 << 20);
- DDD("got memory lot %d addrr %x", mSlot, mAddressOffSet);
+ DDD("got memory lot %d addrr %lu", mSlot, mAddressOffSet);
mHasAddressSpaceMemory = true;
}
transport->writeParam(mVersion, 0, mAddressOffSet);
@@ -62,7 +62,7 @@ void MediaH264Decoder::initH264Context(unsigned int width, unsigned int height,
MediaOperation::InitContext, mAddressOffSet);
auto *retptr = transport->getReturnAddr(mAddressOffSet);
mHostHandle = *(uint64_t *)(retptr);
- DDD("initH264Context: got handle to host %lld", mHostHandle);
+ DDD("initH264Context: got handle to host %lu", mHostHandle);
}
void MediaH264Decoder::resetH264Context(unsigned int width, unsigned int height,
@@ -87,7 +87,7 @@ void MediaH264Decoder::resetH264Context(unsigned int width, unsigned int height,
void MediaH264Decoder::destroyH264Context() {
- DDD("return memory lot %d addrr %x", (int)(mAddressOffSet >> 23),
+ DDD("return memory lot %d addrr %lu", (int)(mAddressOffSet >> 23),
mAddressOffSet);
auto transport = GoldfishMediaTransport::getInstance();
transport->writeParam((uint64_t)mHostHandle, 0, mAddressOffSet);
@@ -99,7 +99,7 @@ void MediaH264Decoder::destroyH264Context() {
h264_result_t MediaH264Decoder::decodeFrame(uint8_t *img, size_t szBytes,
uint64_t pts) {
- DDD("decode frame: use handle to host %lld", mHostHandle);
+ DDD("decode frame: use handle to host %lu", mHostHandle);
h264_result_t res = {0, 0};
if (!mHasAddressSpaceMemory) {
ALOGE("%s no address space memory", __func__);
@@ -126,12 +126,28 @@ h264_result_t MediaH264Decoder::decodeFrame(uint8_t *img, size_t szBytes,
return res;
}
+void MediaH264Decoder::sendMetadata(MetaDataColorAspects *ptr) {
+ DDD("send metadata to host %p", ptr);
+ if (!mHasAddressSpaceMemory) {
+ ALOGE("%s no address space memory", __func__);
+ return;
+ }
+ MetaDataColorAspects& meta = *ptr;
+ auto transport = GoldfishMediaTransport::getInstance();
+ transport->writeParam((uint64_t)mHostHandle, 0, mAddressOffSet);
+ transport->writeParam(meta.type, 1, mAddressOffSet);
+ transport->writeParam(meta.primaries, 2, mAddressOffSet);
+ transport->writeParam(meta.range, 3, mAddressOffSet);
+ transport->writeParam(meta.transfer, 4, mAddressOffSet);
+ transport->sendOperation(MediaCodecType::H264Codec, MediaOperation::SendMetadata, mAddressOffSet);
+}
+
void MediaH264Decoder::flush() {
if (!mHasAddressSpaceMemory) {
ALOGE("%s no address space memory", __func__);
return;
}
- DDD("flush: use handle to host %lld", mHostHandle);
+ DDD("flush: use handle to host %lu", mHostHandle);
auto transport = GoldfishMediaTransport::getInstance();
transport->writeParam((uint64_t)mHostHandle, 0, mAddressOffSet);
transport->sendOperation(MediaCodecType::H264Codec, MediaOperation::Flush,
@@ -139,7 +155,7 @@ void MediaH264Decoder::flush() {
}
h264_image_t MediaH264Decoder::getImage() {
- DDD("getImage: use handle to host %lld", mHostHandle);
+ DDD("getImage: use handle to host %lu", mHostHandle);
h264_image_t res{};
if (!mHasAddressSpaceMemory) {
ALOGE("%s no address space memory", __func__);
@@ -174,7 +190,7 @@ h264_image_t MediaH264Decoder::getImage() {
h264_image_t
MediaH264Decoder::renderOnHostAndReturnImageMetadata(int hostColorBufferId) {
- DDD("%s: use handle to host %lld", __func__, mHostHandle);
+ DDD("%s: use handle to host %lu", __func__, mHostHandle);
h264_image_t res{};
if (hostColorBufferId < 0) {
ALOGE("%s negative color buffer id %d", __func__, hostColorBufferId);
diff --git a/system/codecs/c2/decoders/avcdec/MediaH264Decoder.h b/system/codecs/c2/decoders/avcdec/MediaH264Decoder.h
index 1c1b2623..e184cbd0 100644
--- a/system/codecs/c2/decoders/avcdec/MediaH264Decoder.h
+++ b/system/codecs/c2/decoders/avcdec/MediaH264Decoder.h
@@ -17,6 +17,8 @@
#ifndef GOLDFISH_MEDIA_H264_DEC_H_
#define GOLDFISH_MEDIA_H264_DEC_H_
+#include "goldfish_media_utils.h"
+
struct h264_init_result_t {
uint64_t host_handle;
int ret;
@@ -89,5 +91,14 @@ class MediaH264Decoder {
// ask host to render to hostColorBufferId, return only image metadata back
// to guest
h264_image_t renderOnHostAndReturnImageMetadata(int hostColorBufferId);
+
+ // send metadata about the bitstream to host, such as color aspects that
+ // are set by the framework, e.g., color primaries (601, 709 etc), range
+ // (full range or limited range), transfer etc. given metadata could be
+ // of all kinds of types, the convention is that the first field server as
+ // metadata type id. host will check the type id to decide what to do with
+ // it; unrecognized typeid will be discarded by host side.
+
+ void sendMetadata(MetaDataColorAspects *ptr);
};
#endif
diff --git a/system/codecs/c2/decoders/base/include/goldfish_media_utils.h b/system/codecs/c2/decoders/base/include/goldfish_media_utils.h
index efa88593..a45cda9f 100644
--- a/system/codecs/c2/decoders/base/include/goldfish_media_utils.h
+++ b/system/codecs/c2/decoders/base/include/goldfish_media_utils.h
@@ -26,6 +26,13 @@ enum class MediaCodecType : __u8 {
Max = 4,
};
+struct MetaDataColorAspects {
+ uint64_t type = 1;
+ uint64_t primaries;
+ uint64_t range;
+ uint64_t transfer;
+};
+
enum class MediaOperation : __u8 {
InitContext = 0,
DestroyContext = 1,
@@ -33,7 +40,8 @@ enum class MediaOperation : __u8 {
GetImage = 3,
Flush = 4,
Reset = 5,
- Max = 6,
+ SendMetadata = 6,
+ Max = 7,
};
// This class will abstract away the knowledge required to send media codec data
diff --git a/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.cpp b/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.cpp
index 7008bd5d..13e9515d 100644
--- a/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.cpp
+++ b/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.cpp
@@ -347,6 +347,13 @@ class C2GoldfishHevcDec::IntfImpl : public SimpleInterface<void>::BaseParams {
int height() const { return mSize->height; }
+ int primaries() const { return mColorAspects->primaries; }
+
+ int range() const { return mColorAspects->range; }
+
+ int transfer() const { return mColorAspects->transfer; }
+
+
private:
std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
@@ -404,10 +411,11 @@ void C2GoldfishHevcDec::onRelease() {
}
void C2GoldfishHevcDec::decodeHeaderAfterFlush() {
- if (mContext && !mCsd0.empty() && !mCsd1.empty()) {
+ DDD("calling %s", __func__);
+ if (mContext && !mCsd0.empty()) {
mContext->decodeFrame(&(mCsd0[0]), mCsd0.size(), 0);
- mContext->decodeFrame(&(mCsd1[0]), mCsd1.size(), 0);
- DDD("resending csd0 and csd1");
+ DDD("resending csd0");
+ DDD("calling %s success", __func__);
}
}
@@ -447,6 +455,30 @@ c2_status_t C2GoldfishHevcDec::onFlush_sm() {
return C2_OK;
}
+void C2GoldfishHevcDec::sendMetadata() {
+ // compare and send if changed
+ MetaDataColorAspects currentMetaData = {1, 0, 0, 0};
+ currentMetaData.primaries = mIntf->primaries();
+ currentMetaData.range = mIntf->range();
+ currentMetaData.transfer = mIntf->transfer();
+
+ DDD("metadata primaries %d range %d transfer %d",
+ (int)(currentMetaData.primaries),
+ (int)(currentMetaData.range),
+ (int)(currentMetaData.transfer)
+ );
+
+ if (mSentMetadata.primaries == currentMetaData.primaries &&
+ mSentMetadata.range == currentMetaData.range &&
+ mSentMetadata.transfer == currentMetaData.transfer) {
+ DDD("metadata is the same, no need to update");
+ return;
+ }
+ std::swap(mSentMetadata, currentMetaData);
+
+ mContext->sendMetadata(&(mSentMetadata));
+}
+
status_t C2GoldfishHevcDec::createDecoder() {
DDD("creating hevc context now w %d h %d", mWidth, mHeight);
@@ -874,9 +906,6 @@ void C2GoldfishHevcDec::process(const std::unique_ptr<C2Work> &work,
if (mCsd0.empty()) {
mCsd0.assign(mInPBuffer, mInPBuffer + mInPBufferSize);
DDD("assign to csd0 with %d bytpes", mInPBufferSize);
- } else if (mCsd1.empty()) {
- mCsd1.assign(mInPBuffer, mInPBuffer + mInPBufferSize);
- DDD("assign to csd1 with %d bytpes", mInPBufferSize);
}
// this is not really a valid pts from config
removePts(mPts);
@@ -885,7 +914,15 @@ void C2GoldfishHevcDec::process(const std::unique_ptr<C2Work> &work,
bool whChanged = false;
if (GoldfishHevcHelper::isVpsFrame(mInPBuffer, mInPBufferSize)) {
mHevcHelper.reset(new GoldfishHevcHelper(mWidth, mHeight));
- whChanged = mHevcHelper->decodeHeader(mInPBuffer, mInPBufferSize);
+ bool headerStatus = true;
+ whChanged = mHevcHelper->decodeHeader(
+ mInPBuffer, mInPBufferSize, headerStatus);
+ if (!headerStatus) {
+ mSignalledError = true;
+ work->workletsProcessed = 1u;
+ work->result = C2_CORRUPTED;
+ return;
+ }
if (whChanged) {
DDD("w changed from old %d to new %d\n", mWidth, mHevcHelper->getWidth());
DDD("h changed from old %d to new %d\n", mHeight, mHevcHelper->getHeight());
@@ -922,6 +959,8 @@ void C2GoldfishHevcDec::process(const std::unique_ptr<C2Work> &work,
} // end of whChanged
} // end of isVpsFrame
+ sendMetadata();
+
uint32_t delay;
GETTIME(&mTimeStart, nullptr);
TIME_DIFF(mTimeEnd, mTimeStart, delay);
diff --git a/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.h b/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.h
index fe080cfa..bc3d65b2 100644
--- a/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.h
+++ b/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.h
@@ -142,6 +142,10 @@ class C2GoldfishHevcDec : public SimpleC2Component {
}
} mBitstreamColorAspects;
+ MetaDataColorAspects mSentMetadata = {1, 0, 0, 0};
+
+ void sendMetadata();
+
// profile
struct timeval mTimeStart;
struct timeval mTimeEnd;
diff --git a/system/codecs/c2/decoders/hevcdec/GoldfishHevcHelper.cpp b/system/codecs/c2/decoders/hevcdec/GoldfishHevcHelper.cpp
index 1b93a0d9..d3117a78 100644
--- a/system/codecs/c2/decoders/hevcdec/GoldfishHevcHelper.cpp
+++ b/system/codecs/c2/decoders/hevcdec/GoldfishHevcHelper.cpp
@@ -188,7 +188,9 @@ bool GoldfishHevcHelper::isVpsFrame(const uint8_t* frame, int inSize) {
}
}
-bool GoldfishHevcHelper::decodeHeader(const uint8_t *frame, int inSize) {
+bool GoldfishHevcHelper::decodeHeader(const uint8_t *frame, int inSize,
+ bool &helperstatus) {
+ helperstatus = true;
// should we check the header for vps/sps/pps frame ? otherwise
// there is no point calling decoder
if (!isVpsFrame(frame, inSize)) {
@@ -220,6 +222,8 @@ bool GoldfishHevcHelper::decodeHeader(const uint8_t *frame, int inSize) {
ALOGE("failed to call decoder function for header\n");
ALOGE("error in %s: 0x%x", __func__,
ps_decode_op->u4_error_code);
+ helperstatus = false;
+ return false;
}
if (IVD_RES_CHANGED == (ps_decode_op->u4_error_code & IVD_ERROR_MASK)) {
diff --git a/system/codecs/c2/decoders/hevcdec/GoldfishHevcHelper.h b/system/codecs/c2/decoders/hevcdec/GoldfishHevcHelper.h
index 09de8301..36a496b7 100644
--- a/system/codecs/c2/decoders/hevcdec/GoldfishHevcHelper.h
+++ b/system/codecs/c2/decoders/hevcdec/GoldfishHevcHelper.h
@@ -37,9 +37,9 @@ class GoldfishHevcHelper {
public:
// return true if decoding finds out w/h changed;
// otherwise false
- bool decodeHeader(const uint8_t *frame, int inSize);
- int getWidth() const { return mWidth; }
- int getHeight() const { return mHeight; }
+ bool decodeHeader(const uint8_t *frame, int inSize, bool &status);
+ int getWidth() const { return mWidth; }
+ int getHeight() const { return mHeight; }
private:
void createDecoder();
diff --git a/system/codecs/c2/decoders/hevcdec/MediaHevcDecoder.cpp b/system/codecs/c2/decoders/hevcdec/MediaHevcDecoder.cpp
index bb2fbfa5..f1bc356f 100644
--- a/system/codecs/c2/decoders/hevcdec/MediaHevcDecoder.cpp
+++ b/system/codecs/c2/decoders/hevcdec/MediaHevcDecoder.cpp
@@ -126,6 +126,22 @@ hevc_result_t MediaHevcDecoder::decodeFrame(uint8_t *img, size_t szBytes,
return res;
}
+void MediaHevcDecoder::sendMetadata(MetaDataColorAspects *ptr) {
+ DDD("send metadata to host %p", ptr);
+ if (!mHasAddressSpaceMemory) {
+ ALOGE("%s no address space memory", __func__);
+ return;
+ }
+ MetaDataColorAspects& meta = *ptr;
+ auto transport = GoldfishMediaTransport::getInstance();
+ transport->writeParam((uint64_t)mHostHandle, 0, mAddressOffSet);
+ transport->writeParam(meta.type, 1, mAddressOffSet);
+ transport->writeParam(meta.primaries, 2, mAddressOffSet);
+ transport->writeParam(meta.range, 3, mAddressOffSet);
+ transport->writeParam(meta.transfer, 4, mAddressOffSet);
+ transport->sendOperation(MediaCodecType::HevcCodec, MediaOperation::SendMetadata, mAddressOffSet);
+}
+
void MediaHevcDecoder::flush() {
if (!mHasAddressSpaceMemory) {
ALOGE("%s no address space memory", __func__);
diff --git a/system/codecs/c2/decoders/hevcdec/MediaHevcDecoder.h b/system/codecs/c2/decoders/hevcdec/MediaHevcDecoder.h
index 8dfb0cfa..878950e7 100644
--- a/system/codecs/c2/decoders/hevcdec/MediaHevcDecoder.h
+++ b/system/codecs/c2/decoders/hevcdec/MediaHevcDecoder.h
@@ -17,6 +17,8 @@
#ifndef GOLDFISH_MEDIA_Hevc_DEC_H_
#define GOLDFISH_MEDIA_Hevc_DEC_H_
+#include "goldfish_media_utils.h"
+
struct hevc_init_result_t {
uint64_t host_handle;
int ret;
@@ -89,5 +91,8 @@ class MediaHevcDecoder {
// ask host to render to hostColorBufferId, return only image metadata back
// to guest
hevc_image_t renderOnHostAndReturnImageMetadata(int hostColorBufferId);
+
+ void sendMetadata(MetaDataColorAspects *ptr);
+
};
#endif
diff --git a/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.cpp b/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.cpp
index 99f0469a..be6428e9 100644
--- a/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.cpp
+++ b/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.cpp
@@ -324,6 +324,12 @@ class C2GoldfishVpxDec::IntfImpl : public SimpleInterface<void>::BaseParams {
int height() const { return mSize->height; }
+ int primaries() const { return mDefaultColorAspects->primaries; }
+
+ int range() const { return mDefaultColorAspects->range; }
+
+ int transfer() const { return mDefaultColorAspects->transfer; }
+
static C2R Hdr10PlusInfoInputSetter(bool mayBlock,
C2P<C2StreamHdr10PlusInfo::input> &me) {
(void)mayBlock;
@@ -416,6 +422,30 @@ void C2GoldfishVpxDec::onReset() {
void C2GoldfishVpxDec::onRelease() { destroyDecoder(); }
+void C2GoldfishVpxDec::sendMetadata() {
+ // compare and send if changed
+ MetaDataColorAspects currentMetaData = {1, 0, 0, 0};
+ currentMetaData.primaries = mIntf->primaries();
+ currentMetaData.range = mIntf->range();
+ currentMetaData.transfer = mIntf->transfer();
+
+ DDD("metadata primaries %d range %d transfer %d",
+ (int)(currentMetaData.primaries),
+ (int)(currentMetaData.range),
+ (int)(currentMetaData.transfer)
+ );
+
+ if (mSentMetadata.primaries == currentMetaData.primaries &&
+ mSentMetadata.range == currentMetaData.range &&
+ mSentMetadata.transfer == currentMetaData.transfer) {
+ DDD("metadata is the same, no need to update");
+ return;
+ }
+ std::swap(mSentMetadata, currentMetaData);
+
+ vpx_codec_send_metadata(mCtx, &(mSentMetadata));
+}
+
c2_status_t C2GoldfishVpxDec::onFlush_sm() {
if (mFrameParallelMode) {
// Flush decoder by passing nullptr data ptr and 0 size.
@@ -609,6 +639,8 @@ void C2GoldfishVpxDec::process(const std::unique_ptr<C2Work> &work,
}
}
+ sendMetadata();
+
if (inSize) {
uint8_t *bitstream = const_cast<uint8_t *>(rView.data() + inOffset);
vpx_codec_err_t err = vpx_codec_decode(
diff --git a/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.h b/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.h
index 4b356da5..738d9fc6 100644
--- a/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.h
+++ b/system/codecs/c2/decoders/vpxdec/C2GoldfishVpxDec.h
@@ -16,6 +16,7 @@
#pragma once
+#include "goldfish_media_utils.h"
#include "goldfish_vpx_defs.h"
#include <SimpleC2Component.h>
@@ -95,6 +96,9 @@ struct C2GoldfishVpxDec : public SimpleC2Component {
const std::shared_ptr<C2BlockPool> &pool,
const std::unique_ptr<C2Work> &work);
+ MetaDataColorAspects mSentMetadata = {1, 0, 0, 0};
+ void sendMetadata();
+
C2_DO_NOT_COPY(C2GoldfishVpxDec);
};
diff --git a/system/codecs/c2/decoders/vpxdec/goldfish_vpx_defs.h b/system/codecs/c2/decoders/vpxdec/goldfish_vpx_defs.h
index bbcc8059..1be05c9f 100644
--- a/system/codecs/c2/decoders/vpxdec/goldfish_vpx_defs.h
+++ b/system/codecs/c2/decoders/vpxdec/goldfish_vpx_defs.h
@@ -61,4 +61,6 @@ int vpx_codec_flush(vpx_codec_ctx_t *ctx);
int vpx_codec_decode(vpx_codec_ctx_t *ctx, const uint8_t *data,
unsigned int data_sz, void *user_priv, long deadline);
+void vpx_codec_send_metadata(vpx_codec_ctx_t *ctx, void*ptr);
+
#endif // MY_VPX_DEFS_H_
diff --git a/system/codecs/c2/decoders/vpxdec/goldfish_vpx_impl.cpp b/system/codecs/c2/decoders/vpxdec/goldfish_vpx_impl.cpp
index d008efe6..e1fa879f 100644
--- a/system/codecs/c2/decoders/vpxdec/goldfish_vpx_impl.cpp
+++ b/system/codecs/c2/decoders/vpxdec/goldfish_vpx_impl.cpp
@@ -142,6 +142,17 @@ vpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t *ctx, int hostColorBufferId) {
return &(ctx->myImg);
}
+void vpx_codec_send_metadata(vpx_codec_ctx_t *ctx, void *ptr) {
+ MetaDataColorAspects& meta = *(MetaDataColorAspects*)ptr;
+ auto transport = GoldfishMediaTransport::getInstance();
+ transport->writeParam(ctx->id, 0, ctx->address_offset);
+ transport->writeParam(meta.type, 1, ctx->address_offset);
+ transport->writeParam(meta.primaries, 2, ctx->address_offset);
+ transport->writeParam(meta.range, 3, ctx->address_offset);
+ transport->writeParam(meta.transfer, 4, ctx->address_offset);
+ sendVpxOperation(ctx, MediaOperation::SendMetadata);
+}
+
int vpx_codec_flush(vpx_codec_ctx_t *ctx) {
DDD("%s %d", __func__, __LINE__);
if (!ctx) {
diff --git a/system/hwc2/DisplayFinder.cpp b/system/hwc2/DisplayFinder.cpp
index a55a49d6..2016c4bf 100644
--- a/system/hwc2/DisplayFinder.cpp
+++ b/system/hwc2/DisplayFinder.cpp
@@ -110,7 +110,7 @@ HWC2::Error findGoldfishPrimaryDisplay(
rcEnc->rcGetFBDisplayConfigsParam(rcEnc, configId, FB_HEIGHT), //
rcEnc->rcGetFBDisplayConfigsParam(rcEnc, configId, FB_XDPI), //
rcEnc->rcGetFBDisplayConfigsParam(rcEnc, configId, FB_YDPI), //
- getVsyncForDisplay(drmPresenter, configId) //
+ getVsyncForDisplay(drmPresenter, display.displayId) //
));
}
} else {
diff --git a/system/hwc2/HostComposer.cpp b/system/hwc2/HostComposer.cpp
index 5bf324e0..472e7829 100644
--- a/system/hwc2/HostComposer.cpp
+++ b/system/hwc2/HostComposer.cpp
@@ -570,7 +570,7 @@ std::tuple<HWC2::Error, base::unique_fd> HostComposer::presentDisplay(
display->clearReleaseFencesAndIdsLocked();
if (numLayer == 0) {
- ALOGW(
+ ALOGV(
"%s display has no layers to compose, flushing client target buffer.",
__FUNCTION__);
diff --git a/system/hwc3/HostFrameComposer.cpp b/system/hwc3/HostFrameComposer.cpp
index 7b090c2d..f976e053 100644
--- a/system/hwc3/HostFrameComposer.cpp
+++ b/system/hwc3/HostFrameComposer.cpp
@@ -578,7 +578,7 @@ HWC3::Error HostFrameComposer::presentDisplay(
displayId, static_cast<int>(layers.size()));
if (numLayer == 0) {
- ALOGW(
+ ALOGV(
"%s display has no layers to compose, flushing client target buffer.",
__FUNCTION__);
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index 76e86773..6cc7010d 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -7816,6 +7816,63 @@ public:
return VK_SUCCESS;
}
+ VkResult on_vkCreateGraphicsPipelines(
+ void* context,
+ VkResult input_result,
+ VkDevice device,
+ VkPipelineCache pipelineCache,
+ uint32_t createInfoCount,
+ const VkGraphicsPipelineCreateInfo* pCreateInfos,
+ const VkAllocationCallbacks* pAllocator,
+ VkPipeline* pPipelines) {
+ (void)input_result;
+ VkEncoder* enc = (VkEncoder*)context;
+ std::vector<VkGraphicsPipelineCreateInfo> localCreateInfos(
+ pCreateInfos, pCreateInfos + createInfoCount);
+ for (VkGraphicsPipelineCreateInfo& graphicsPipelineCreateInfo : localCreateInfos) {
+ // dEQP-VK.api.pipeline.pipeline_invalid_pointers_unused_structs#graphics
+ bool requireViewportState = false;
+ // VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00750
+ requireViewportState |= graphicsPipelineCreateInfo.pRasterizationState != nullptr &&
+ graphicsPipelineCreateInfo.pRasterizationState->rasterizerDiscardEnable
+ == VK_FALSE;
+ // VUID-VkGraphicsPipelineCreateInfo-pViewportState-04892
+#ifdef VK_EXT_extended_dynamic_state2
+ if (!requireViewportState && graphicsPipelineCreateInfo.pDynamicState) {
+ for (uint32_t i = 0; i <
+ graphicsPipelineCreateInfo.pDynamicState->dynamicStateCount; i++) {
+ if (VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT ==
+ graphicsPipelineCreateInfo.pDynamicState->pDynamicStates[i]) {
+ requireViewportState = true;
+ break;
+ }
+ }
+ }
+#endif // VK_EXT_extended_dynamic_state2
+ if (!requireViewportState) {
+ graphicsPipelineCreateInfo.pViewportState = nullptr;
+ }
+
+ // It has the same requirement as for pViewportState.
+ bool shouldIncludeFragmentShaderState = requireViewportState;
+
+ // VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00751
+ if (!shouldIncludeFragmentShaderState) {
+ graphicsPipelineCreateInfo.pMultisampleState = nullptr;
+ }
+
+ // VUID-VkGraphicsPipelineCreateInfo-renderPass-06043
+ // VUID-VkGraphicsPipelineCreateInfo-renderPass-06044
+ if (graphicsPipelineCreateInfo.renderPass == VK_NULL_HANDLE
+ || !shouldIncludeFragmentShaderState) {
+ graphicsPipelineCreateInfo.pDepthStencilState = nullptr;
+ graphicsPipelineCreateInfo.pColorBlendState = nullptr;
+ }
+ }
+ return enc->vkCreateGraphicsPipelines(device, pipelineCache, localCreateInfos.size(),
+ localCreateInfos.data(), pAllocator, pPipelines, true /* do lock */);
+ }
+
uint32_t getApiVersionFromInstance(VkInstance instance) const {
AutoLock<RecursiveLock> lock(mLock);
uint32_t api = kDefaultApiVersion;
@@ -9046,6 +9103,18 @@ VkResult ResourceTracker::on_vkQueueSignalReleaseImageANDROID(
return mImpl->on_vkQueueSignalReleaseImageANDROID(context, input_result, queue, waitSemaphoreCount, pWaitSemaphores, image, pNativeFenceFd);
}
+VkResult ResourceTracker::on_vkCreateGraphicsPipelines(
+ void* context,
+ VkResult input_result,
+ VkDevice device,
+ VkPipelineCache pipelineCache,
+ uint32_t createInfoCount,
+ const VkGraphicsPipelineCreateInfo* pCreateInfos,
+ const VkAllocationCallbacks* pAllocator,
+ VkPipeline* pPipelines) {
+ return mImpl->on_vkCreateGraphicsPipelines(context, input_result, device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
+}
+
void ResourceTracker::deviceMemoryTransform_tohost(
VkDeviceMemory* memory, uint32_t memoryCount,
VkDeviceSize* offset, uint32_t offsetCount,
diff --git a/system/vulkan_enc/ResourceTracker.h b/system/vulkan_enc/ResourceTracker.h
index e25e75d3..b50635dc 100644
--- a/system/vulkan_enc/ResourceTracker.h
+++ b/system/vulkan_enc/ResourceTracker.h
@@ -627,6 +627,16 @@ public:
VkImage image,
int* pNativeFenceFd);
+ VkResult on_vkCreateGraphicsPipelines(
+ void* context,
+ VkResult input_result,
+ VkDevice device,
+ VkPipelineCache pipelineCache,
+ uint32_t createInfoCount,
+ const VkGraphicsPipelineCreateInfo* pCreateInfos,
+ const VkAllocationCallbacks* pAllocator,
+ VkPipeline* pPipelines);
+
uint8_t* getMappedPointer(VkDeviceMemory memory);
VkDeviceSize getMappedSize(VkDeviceMemory memory);
VkDeviceSize getNonCoherentExtendedSize(VkDevice device, VkDeviceSize basicSize) const;
diff --git a/system/vulkan_enc/func_table.cpp b/system/vulkan_enc/func_table.cpp
index 4e17d42e..54b232e7 100644
--- a/system/vulkan_enc/func_table.cpp
+++ b/system/vulkan_enc/func_table.cpp
@@ -769,7 +769,8 @@ static VkResult entry_vkCreateGraphicsPipelines(
AEMU_SCOPED_TRACE("vkCreateGraphicsPipelines");
auto vkEnc = ResourceTracker::getThreadLocalEncoder();
VkResult vkCreateGraphicsPipelines_VkResult_return = (VkResult)0;
- vkCreateGraphicsPipelines_VkResult_return = vkEnc->vkCreateGraphicsPipelines(device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines, true /* do lock */);
+ auto resources = ResourceTracker::get();
+ vkCreateGraphicsPipelines_VkResult_return = resources->on_vkCreateGraphicsPipelines(vkEnc, VK_SUCCESS, device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
return vkCreateGraphicsPipelines_VkResult_return;
}
static VkResult entry_vkCreateComputePipelines(