goldfish-codecs: render vp8 and vp9 on host
Refactor guest vpx decoder to work with host.
BUG: 150378029
Test: presubmit
Merged-In: Ie1ba9b4d3ae1b41c1fbddb0b56faf51f8ef9d0dc
Change-Id: I62fdc8f93a263075da71327f88b266471a03c1a8
diff --git a/system/codecs/omx/plugin/GoldfishOMXPlugin.cpp b/system/codecs/omx/plugin/GoldfishOMXPlugin.cpp
index 47c22a3..7ff9fa4 100644
--- a/system/codecs/omx/plugin/GoldfishOMXPlugin.cpp
+++ b/system/codecs/omx/plugin/GoldfishOMXPlugin.cpp
@@ -76,10 +76,12 @@
}
static const GoldfishComponent kComponents[] = {
- { "OMX.google.goldfish.vp8.decoder", "vpxdec", "video_decoder.vp8" },
- { "OMX.google.goldfish.vp9.decoder", "vpxdec", "video_decoder.vp9" },
- { "OMX.google.goldfish.h264.decoder", "avcdec", "video_decoder.avc" },
- { "OMX.android.goldfish.h264.decoder", "avcdec", "video_decoder.avc" },
+ {"OMX.google.goldfish.vp8.decoder", "vpxdec", "video_decoder.vp8"},
+ {"OMX.google.goldfish.vp9.decoder", "vpxdec", "video_decoder.vp9"},
+ {"OMX.google.goldfish.h264.decoder", "avcdec", "video_decoder.avc"},
+ {"OMX.android.goldfish.vp8.decoder", "vpxdec", "video_decoder.vp8"},
+ {"OMX.android.goldfish.vp9.decoder", "vpxdec", "video_decoder.vp9"},
+ {"OMX.android.goldfish.h264.decoder", "avcdec", "video_decoder.avc"},
};
static std::vector<GoldfishComponent> kActiveComponents;
diff --git a/system/codecs/omx/vpxdec/Android.mk b/system/codecs/omx/vpxdec/Android.mk
index 6374ac3..ce2ab89 100644
--- a/system/codecs/omx/vpxdec/Android.mk
+++ b/system/codecs/omx/vpxdec/Android.mk
@@ -34,12 +34,21 @@
libhidlbase_impl_internal \
libbase
+LOCAL_HEADER_LIBRARIES += libui_headers \
+ libnativewindow_headers \
+ libhardware_headers \
+ libarect_headers \
+ libarect_headers_for_ndk
+
LOCAL_SHARED_LIBRARIES := \
libbinder \
libutils \
liblog \
libcutils \
+ libui \
android.hardware.media.omx@1.0 \
+ android.hardware.graphics.allocator@3.0 \
+ android.hardware.graphics.mapper@3.0 \
libstagefright_foundation
$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
diff --git a/system/codecs/omx/vpxdec/GoldfishVPX.cpp b/system/codecs/omx/vpxdec/GoldfishVPX.cpp
index 5b9fb2d..2e7043f 100644
--- a/system/codecs/omx/vpxdec/GoldfishVPX.cpp
+++ b/system/codecs/omx/vpxdec/GoldfishVPX.cpp
@@ -19,11 +19,29 @@
#include <utils/misc.h>
//#include "OMX_VideoExt.h"
+#define DEBUG 0
+#if DEBUG
+#define DDD(...) ALOGD(__VA_ARGS__)
+#else
+#define DDD(...) ((void)0)
+#endif
+
#include "GoldfishVPX.h"
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaDefs.h>
+#include <OMX_VideoExt.h>
+#include <inttypes.h>
+
+#include <nativebase/nativebase.h>
+
+#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/3.0/IMapper.h>
+#include <hidl/LegacySupport.h>
+
+using ::android::hardware::graphics::common::V1_0::BufferUsage;
+using ::android::hardware::graphics::common::V1_2::PixelFormat;
namespace android {
@@ -35,19 +53,26 @@
{ OMX_VIDEO_VP9Profile2HDR10Plus, OMX_VIDEO_VP9Level5 },
};
-GoldfishVPX::GoldfishVPX(
- const char *name,
- const char *componentRole,
- OMX_VIDEO_CODINGTYPE codingType,
- const OMX_CALLBACKTYPE *callbacks,
- OMX_PTR appData,
- OMX_COMPONENTTYPE **component)
+GoldfishVPX::GoldfishVPX(const char* name,
+ const char* componentRole,
+ OMX_VIDEO_CODINGTYPE codingType,
+ const OMX_CALLBACKTYPE* callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE** component,
+ RenderMode renderMode)
: GoldfishVideoDecoderOMXComponent(
- name, componentRole, codingType,
- codingType == OMX_VIDEO_CodingVP8 ? NULL : kVP9ProfileLevels,
- codingType == OMX_VIDEO_CodingVP8 ? 0 : NELEM(kVP9ProfileLevels),
- 320 /* width */, 240 /* height */, callbacks, appData, component),
+ name,
+ componentRole,
+ codingType,
+ codingType == OMX_VIDEO_CodingVP8 ? NULL : kVP9ProfileLevels,
+ codingType == OMX_VIDEO_CodingVP8 ? 0 : NELEM(kVP9ProfileLevels),
+ 320 /* width */,
+ 240 /* height */,
+ callbacks,
+ appData,
+ component),
mMode(codingType == OMX_VIDEO_CodingVP8 ? MODE_VP8 : MODE_VP9),
+ mRenderMode(renderMode),
mEOSStatus(INPUT_DATA_AVAILABLE),
mCtx(NULL),
mFrameParallelMode(false),
@@ -55,17 +80,19 @@
mImg(NULL) {
// arbitrary from avc/hevc as vpx does not specify a min compression ratio
const size_t kMinCompressionRatio = mMode == MODE_VP8 ? 2 : 4;
- const char *mime = mMode == MODE_VP8 ? MEDIA_MIMETYPE_VIDEO_VP8 : MEDIA_MIMETYPE_VIDEO_VP9;
- const size_t kMaxOutputBufferSize = 2560 * 2560 * 3 / 2;
- initPorts(
- kNumBuffers, kMaxOutputBufferSize / kMinCompressionRatio /* inputBufferSize */,
- kNumBuffers, mime, kMinCompressionRatio);
- ALOGE("calling constructor of GoldfishVPX");
- CHECK_EQ(initDecoder(), (status_t)OK);
+ const char* mime = mMode == MODE_VP8 ? MEDIA_MIMETYPE_VIDEO_VP8
+ : MEDIA_MIMETYPE_VIDEO_VP9;
+ const size_t kMaxOutputBufferSize = 3840 * 2160 * 3 / 2; // 4k
+ initPorts(kNumBuffers,
+ kMaxOutputBufferSize / kMinCompressionRatio /* inputBufferSize */,
+ kNumBuffers, mime, kMinCompressionRatio);
+ ALOGI("calling constructor of GoldfishVPX");
+ // wait till later
+ // CHECK_EQ(initDecoder(), (status_t)OK);
}
GoldfishVPX::~GoldfishVPX() {
- ALOGE("calling destructor of GoldfishVPX");
+ ALOGI("calling destructor of GoldfishVPX");
destroyDecoder();
}
@@ -81,25 +108,33 @@
mCtx = new vpx_codec_ctx_t;
mCtx->vpversion = mMode == MODE_VP8 ? 8 : 9;
+ mCtx->version = mEnableAndroidNativeBuffers ? 200 : 100;
+
int vpx_err = 0;
if ((vpx_err = vpx_codec_dec_init(mCtx))) {
ALOGE("vpx decoder failed to initialize. (%d)", vpx_err);
return UNKNOWN_ERROR;
}
+ ALOGI("calling init GoldfishVPX ctx %p", mCtx);
return OK;
}
status_t GoldfishVPX::destroyDecoder() {
- vpx_codec_destroy(mCtx);
- delete mCtx;
- mCtx = NULL;
+ if (mCtx) {
+ ALOGI("calling destroying GoldfishVPX ctx %p", mCtx);
+ vpx_codec_destroy(mCtx);
+ delete mCtx;
+ mCtx = NULL;
+ }
return OK;
}
-void GoldfishVPX::setup_ctx_parameters(vpx_codec_ctx_t* ctx) {
+void GoldfishVPX::setup_ctx_parameters(vpx_codec_ctx_t* ctx,
+ int hostColorBufferId) {
ctx->width = mWidth;
ctx->height = mHeight;
+ ctx->hostColorBufferId = hostColorBufferId;
ctx->outputBufferWidth = outputBufferWidth();
ctx->outputBufferHeight = outputBufferHeight();
OMX_PARAM_PORTDEFINITIONTYPE *outDef = &editPortInfo(kOutputPortIndex)->mDef;
@@ -111,6 +146,7 @@
List<BufferInfo *> &outQueue = getPortQueue(1);
BufferInfo *outInfo = NULL;
OMX_BUFFERHEADERTYPE *outHeader = NULL;
+ DDD("%s %d", __func__, __LINE__);
if (flushDecoder && mFrameParallelMode) {
// Flush decoder by passing NULL data ptr and 0 size.
@@ -136,8 +172,11 @@
}
while (!outQueue.empty()) {
+ DDD("%s %d", __func__, __LINE__);
+ outInfo = *outQueue.begin();
+ outHeader = outInfo->mHeader;
if (mImg == NULL) {
- setup_ctx_parameters(mCtx);
+ setup_ctx_parameters(mCtx, getHostColorBufferId(outHeader));
mImg = vpx_codec_get_frame(mCtx);
if (mImg == NULL) {
break;
@@ -145,8 +184,6 @@
}
uint32_t width = mImg->d_w;
uint32_t height = mImg->d_h;
- outInfo = *outQueue.begin();
- outHeader = outInfo->mHeader;
CHECK(mImg->fmt == VPX_IMG_FMT_I420 || mImg->fmt == VPX_IMG_FMT_I42016);
OMX_COLOR_FORMATTYPE outputColorFormat = OMX_COLOR_FormatYUV420Planar;
int32_t bpp = 1;
@@ -168,11 +205,12 @@
queueOutputFrameConfig(privInfo->mHdr10PlusInfo);
}
- if (outputBufferSafe(outHeader)) {
+ if (outputBufferSafe(outHeader) &&
+ getHostColorBufferId(outHeader) < 0) {
uint8_t *dst = outHeader->pBuffer;
memcpy(dst, mCtx->dst, outHeader->nFilledLen);
} else {
- outHeader->nFilledLen = 0;
+ // outHeader->nFilledLen = 0;
}
mImg = NULL;
@@ -202,6 +240,7 @@
}
bool GoldfishVPX::outputBufferSafe(OMX_BUFFERHEADERTYPE *outHeader) {
+ DDD("%s %d", __func__, __LINE__);
uint32_t width = outputBufferWidth();
uint32_t height = outputBufferHeight();
uint64_t nFilledLen = width;
@@ -221,10 +260,19 @@
}
void GoldfishVPX::onQueueFilled(OMX_U32 /* portIndex */) {
+ DDD("%s %d", __func__, __LINE__);
if (mOutputPortSettingsChange != NONE || mEOSStatus == OUTPUT_FRAMES_FLUSHED) {
return;
}
+ if (mCtx == nullptr) {
+ if (OK != initDecoder()) {
+ ALOGE("Failed to initialize decoder");
+ notify(OMX_EventError, OMX_ErrorUnsupportedSetting, 0, NULL);
+ return;
+ }
+ }
+
List<BufferInfo *> &inQueue = getPortQueue(0);
List<BufferInfo *> &outQueue = getPortQueue(1);
bool EOSseen = false;
@@ -313,6 +361,7 @@
}
void GoldfishVPX::onPortFlushCompleted(OMX_U32 portIndex) {
+ DDD("%s %d", __func__, __LINE__);
if (portIndex == kInputPortIndex) {
bool portWillReset = false;
if (!outputBuffers(
@@ -326,6 +375,7 @@
}
void GoldfishVPX::onReset() {
+ DDD("%s %d", __func__, __LINE__);
bool portWillReset = false;
if (!outputBuffers(
true /* flushDecoder */, false /* display */, false /* eos */, &portWillReset)) {
@@ -336,21 +386,141 @@
mEOSStatus = INPUT_DATA_AVAILABLE;
}
+int GoldfishVPX::getHostColorBufferId(void* header) {
+ DDD("%s %d", __func__, __LINE__);
+ if (mNWBuffers.find(header) == mNWBuffers.end()) {
+ DDD("cannot find color buffer for header %p", header);
+ return -1;
+ }
+ sp<ANativeWindowBuffer> nBuf = mNWBuffers[header];
+ cb_handle_t* handle = (cb_handle_t*)nBuf->handle;
+ DDD("found color buffer for header %p --> %d", header, handle->hostHandle);
+ return handle->hostHandle;
+}
+
+OMX_ERRORTYPE GoldfishVPX::internalGetParameter(OMX_INDEXTYPE index,
+ OMX_PTR params) {
+ const int32_t indexFull = index;
+ switch (indexFull) {
+ case kGetAndroidNativeBufferUsageIndex: {
+ DDD("calling kGetAndroidNativeBufferUsageIndex");
+ GetAndroidNativeBufferUsageParams* nativeBuffersUsage =
+ (GetAndroidNativeBufferUsageParams*)params;
+ nativeBuffersUsage->nUsage =
+ (unsigned int)(BufferUsage::GPU_DATA_BUFFER);
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return GoldfishVideoDecoderOMXComponent::internalGetParameter(
+ index, params);
+ }
+}
+
+OMX_ERRORTYPE GoldfishVPX::internalSetParameter(OMX_INDEXTYPE index,
+ const OMX_PTR params) {
+ // Include extension index OMX_INDEXEXTTYPE.
+ const int32_t indexFull = index;
+
+ switch (indexFull) {
+ case kEnableAndroidNativeBuffersIndex: {
+ DDD("calling kEnableAndroidNativeBuffersIndex");
+ EnableAndroidNativeBuffersParams* enableNativeBuffers =
+ (EnableAndroidNativeBuffersParams*)params;
+ if (enableNativeBuffers) {
+ mEnableAndroidNativeBuffers = enableNativeBuffers->enable;
+ if (mEnableAndroidNativeBuffers == false) {
+ mNWBuffers.clear();
+ DDD("disabled kEnableAndroidNativeBuffersIndex");
+ } else {
+ DDD("enabled kEnableAndroidNativeBuffersIndex");
+ }
+ }
+ return OMX_ErrorNone;
+ }
+
+ case kUseAndroidNativeBufferIndex: {
+ if (mEnableAndroidNativeBuffers == false) {
+ ALOGE("Error: not enabled Android Native Buffers");
+ return OMX_ErrorBadParameter;
+ }
+ UseAndroidNativeBufferParams* use_buffer_params =
+ (UseAndroidNativeBufferParams*)params;
+ if (use_buffer_params) {
+ sp<ANativeWindowBuffer> nBuf = use_buffer_params->nativeBuffer;
+ cb_handle_t* handle = (cb_handle_t*)nBuf->handle;
+ void* dst = NULL;
+ DDD("kUseAndroidNativeBufferIndex with handle %p host color "
+ "handle %d "
+ "calling usebuffer",
+ handle, handle->hostHandle);
+ useBufferCallerLockedAlready(use_buffer_params->bufferHeader,
+ use_buffer_params->nPortIndex,
+ use_buffer_params->pAppPrivate,
+ handle->allocatedSize(),
+ (OMX_U8*)dst);
+ mNWBuffers[*(use_buffer_params->bufferHeader)] =
+ use_buffer_params->nativeBuffer;
+ ;
+ }
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return GoldfishVideoDecoderOMXComponent::internalSetParameter(
+ index, params);
+ }
+}
+
+OMX_ERRORTYPE GoldfishVPX::getExtensionIndex(const char* name,
+ OMX_INDEXTYPE* index) {
+ if (mRenderMode == RenderMode::RENDER_BY_HOST_GPU) {
+ if (!strcmp(name,
+ "OMX.google.android.index.enableAndroidNativeBuffers")) {
+ DDD("calling getExtensionIndex for enable ANB");
+ *(int32_t*)index = kEnableAndroidNativeBuffersIndex;
+ return OMX_ErrorNone;
+ } else if (!strcmp(name,
+ "OMX.google.android.index.useAndroidNativeBuffer")) {
+ *(int32_t*)index = kUseAndroidNativeBufferIndex;
+ return OMX_ErrorNone;
+ } else if (!strcmp(name,
+ "OMX.google.android.index."
+ "getAndroidNativeBufferUsage")) {
+ *(int32_t*)index = kGetAndroidNativeBufferUsageIndex;
+ return OMX_ErrorNone;
+ }
+ }
+ return GoldfishVideoDecoderOMXComponent::getExtensionIndex(name, index);
+}
+
} // namespace android
android::GoldfishOMXComponent *createGoldfishOMXComponent(
const char *name, const OMX_CALLBACKTYPE *callbacks,
OMX_PTR appData, OMX_COMPONENTTYPE **component) {
- if (!strcmp(name, "OMX.google.goldfish.vp8.decoder")) {
+ DDD("%s %d", __func__, __LINE__);
+ // only support vp9 to use host hardware decoder, for now
+ if (!strncmp("OMX.android.goldfish.vp9.decoder", name, 32)) {
return new android::GoldfishVPX(
- name, "video_decoder.vp8", OMX_VIDEO_CodingVP8,
- callbacks, appData, component);
- } else if (!strcmp(name, "OMX.google.goldfish.vp9.decoder")) {
- return new android::GoldfishVPX(
- name, "video_decoder.vp9", OMX_VIDEO_CodingVP9,
- callbacks, appData, component);
- } else {
- CHECK(!"Unknown component");
+ name, "video_decoder.vp9", OMX_VIDEO_CodingVP9, callbacks,
+ appData, component, RenderMode::RENDER_BY_HOST_GPU);
}
+ if (!strncmp("OMX.android.goldfish.vp8.decoder", name, 32)) {
+ return new android::GoldfishVPX(
+ name, "video_decoder.vp8", OMX_VIDEO_CodingVP8, callbacks,
+ appData, component, RenderMode::RENDER_BY_HOST_GPU);
+ }
+ if (!strncmp("OMX.google.goldfish.vp9.decoder", name, 30)) {
+ return new android::GoldfishVPX(
+ name, "video_decoder.vp9", OMX_VIDEO_CodingVP9, callbacks,
+ appData, component, RenderMode::RENDER_BY_GUEST_CPU);
+ }
+ if (!strncmp("OMX.google.goldfish.vp8.decoder", name, 30)) {
+ return new android::GoldfishVPX(
+ name, "video_decoder.vp8", OMX_VIDEO_CodingVP8, callbacks,
+ appData, component, RenderMode::RENDER_BY_GUEST_CPU);
+ }
+ { CHECK(!"Unknown component"); }
return NULL;
}
diff --git a/system/codecs/omx/vpxdec/GoldfishVPX.h b/system/codecs/omx/vpxdec/GoldfishVPX.h
index 2ba8beb..2eb762c 100644
--- a/system/codecs/omx/vpxdec/GoldfishVPX.h
+++ b/system/codecs/omx/vpxdec/GoldfishVPX.h
@@ -21,17 +21,30 @@
#include "GoldfishVideoDecoderOMXComponent.h"
#include "goldfish_vpx_defs.h"
+#include <sys/time.h>
+
+#include <map>
+#include <vector>
+
+#include <ui/GraphicBuffer.h>
+#include <utils/List.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+#include <utils/threads.h>
+#include "gralloc_cb.h"
+
namespace android {
struct ABuffer;
struct GoldfishVPX : public GoldfishVideoDecoderOMXComponent {
- GoldfishVPX(const char *name,
- const char *componentRole,
- OMX_VIDEO_CODINGTYPE codingType,
- const OMX_CALLBACKTYPE *callbacks,
- OMX_PTR appData,
- OMX_COMPONENTTYPE **component);
+ GoldfishVPX(const char* name,
+ const char* componentRole,
+ OMX_VIDEO_CODINGTYPE codingType,
+ const OMX_CALLBACKTYPE* callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE** component,
+ RenderMode renderMode);
protected:
virtual ~GoldfishVPX();
@@ -42,6 +55,15 @@
virtual bool supportDescribeHdrStaticInfo();
virtual bool supportDescribeHdr10PlusInfo();
+ virtual OMX_ERRORTYPE internalGetParameter(OMX_INDEXTYPE index,
+ OMX_PTR params);
+
+ virtual OMX_ERRORTYPE internalSetParameter(OMX_INDEXTYPE index,
+ const OMX_PTR params);
+
+ virtual OMX_ERRORTYPE getExtensionIndex(const char* name,
+ OMX_INDEXTYPE* index);
+
private:
enum {
kNumBuffers = 10
@@ -52,6 +74,12 @@
MODE_VP9
} mMode;
+ RenderMode mRenderMode = RenderMode::RENDER_BY_GUEST_CPU;
+ bool mEnableAndroidNativeBuffers = false;
+ std::map<void*, sp<ANativeWindowBuffer>> mNWBuffers;
+
+ int getHostColorBufferId(void* header);
+
enum {
INPUT_DATA_AVAILABLE, // VPX component is ready to decode data.
INPUT_EOS_SEEN, // VPX component saw EOS and is flushing On2 decoder.
@@ -73,7 +101,7 @@
bool outputBuffers(bool flushDecoder, bool display, bool eos, bool *portWillReset);
bool outputBufferSafe(OMX_BUFFERHEADERTYPE *outHeader);
- void setup_ctx_parameters(vpx_codec_ctx_t*);
+ void setup_ctx_parameters(vpx_codec_ctx_t*, int hostColorBufferId = -1);
DISALLOW_EVIL_CONSTRUCTORS(GoldfishVPX);
};
diff --git a/system/codecs/omx/vpxdec/goldfish_vpx_defs.h b/system/codecs/omx/vpxdec/goldfish_vpx_defs.h
index 1b1358c..25fecde 100644
--- a/system/codecs/omx/vpxdec/goldfish_vpx_defs.h
+++ b/system/codecs/omx/vpxdec/goldfish_vpx_defs.h
@@ -9,6 +9,11 @@
typedef unsigned char uint8_t;
+enum class RenderMode {
+ RENDER_BY_HOST_GPU = 1,
+ RENDER_BY_GUEST_CPU = 2,
+};
+
enum vpx_img_fmt_t {
VPX_IMG_FMT_NONE,
VPX_IMG_FMT_YV12 =
@@ -34,6 +39,11 @@
struct vpx_codec_ctx_t {
int vpversion; //8: vp8 or 9: vp9
+ int version; // 100: return decoded frame to guest; 200: render on host
+ int hostColorBufferId;
+ uint64_t id; // >= 1, unique
+ int memory_slot;
+ uint64_t address_offset = 0;
size_t outputBufferWidth;
size_t outputBufferHeight;
size_t width;
@@ -41,11 +51,12 @@
size_t bpp;
uint8_t *data;
uint8_t *dst;
+ vpx_image_t myImg;
};
int vpx_codec_destroy(vpx_codec_ctx_t*);
int vpx_codec_dec_init(vpx_codec_ctx_t*);
-vpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t*);
+vpx_image_t* vpx_codec_get_frame(vpx_codec_ctx_t*, int hostColorBufferId = -1);
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,
diff --git a/system/codecs/omx/vpxdec/goldfish_vpx_impl.cpp b/system/codecs/omx/vpxdec/goldfish_vpx_impl.cpp
index 0771176..92dfcfa 100644
--- a/system/codecs/omx/vpxdec/goldfish_vpx_impl.cpp
+++ b/system/codecs/omx/vpxdec/goldfish_vpx_impl.cpp
@@ -14,27 +14,73 @@
#include "goldfish_vpx_defs.h"
#include "goldfish_media_utils.h"
-static vpx_image_t myImg;
+#include <memory>
+#include <mutex>
+#include <vector>
+
+#define DEBUG 0
+#if DEBUG
+#define DDD(...) ALOGD(__VA_ARGS__)
+#else
+#define DDD(...) ((void)0)
+#endif
+
+// static vpx_image_t myImg;
+static uint64_t s_CtxId = 0;
+static std::mutex sCtxidMutex;
+
+static uint64_t applyForOneId() {
+ DDD("%s %d", __func__, __LINE__);
+ std::lock_guard<std::mutex> g{sCtxidMutex};
+ ++s_CtxId;
+ return s_CtxId;
+}
static void sendVpxOperation(vpx_codec_ctx_t* ctx, MediaOperation op) {
+ DDD("%s %d", __func__, __LINE__);
+ if (ctx->memory_slot < 0) {
+ ALOGE("ERROR: Failed %s %d: there is no memory slot", __func__,
+ __LINE__);
+ }
auto transport = GoldfishMediaTransport::getInstance();
- transport->sendOperation(
- ctx->vpversion == 8 ?
- MediaCodecType::VP8Codec :
- MediaCodecType::VP9Codec,
- op);
+ transport->sendOperation(ctx->vpversion == 9 ? MediaCodecType::VP9Codec
+ : MediaCodecType::VP8Codec,
+ op, ctx->address_offset);
}
int vpx_codec_destroy(vpx_codec_ctx_t* ctx) {
+ DDD("%s %d", __func__, __LINE__);
+ auto transport = GoldfishMediaTransport::getInstance();
+ transport->writeParam(ctx->id, 0, ctx->address_offset);
sendVpxOperation(ctx, MediaOperation::DestroyContext);
+ transport->returnMemorySlot(ctx->memory_slot);
+ ctx->memory_slot = -1;
return 0;
}
int vpx_codec_dec_init(vpx_codec_ctx_t* ctx) {
+ DDD("%s %d", __func__, __LINE__);
auto transport = GoldfishMediaTransport::getInstance();
+ int slot = transport->getMemorySlot();
+ if (slot < 0) {
+ ALOGE("ERROR: Failed %s %d: cannot get memory slot", __func__,
+ __LINE__);
+ return -1;
+ } else {
+ DDD("got slot %d", slot);
+ }
+ ctx->id = applyForOneId();
+ ctx->memory_slot = slot;
+ ctx->address_offset = static_cast<unsigned int>(slot) * 8 * (1 << 20);
+ DDD("got address offset 0x%x version %d", (int)(ctx->address_offset),
+ ctx->version);
+
// data and dst are on the host side actually
- ctx->data = transport->getInputAddr();
- ctx->dst = transport->getOutputAddr();
+ ctx->data = transport->getInputAddr(ctx->address_offset);
+ ctx->dst = transport->getInputAddr(
+ ctx->address_offset); // re-use input address
+ transport->writeParam(ctx->id, 0, ctx->address_offset);
+ transport->writeParam(ctx->version, 1, ctx->address_offset);
sendVpxOperation(ctx, MediaOperation::InitContext);
return 0;
}
@@ -44,7 +90,9 @@
return *pint;
}
-static void getVpxFrame(uint8_t* ptr) {
+// vpx_image_t myImg;
+static void getVpxFrame(uint8_t* ptr, vpx_image_t& myImg) {
+ DDD("%s %d", __func__, __LINE__);
uint8_t* imgptr = (ptr + 8);
myImg.fmt = *(vpx_img_fmt_t*)imgptr;
imgptr += 8;
@@ -53,31 +101,41 @@
myImg.d_h = *(unsigned int *)imgptr;
imgptr += 8;
myImg.user_priv = (void*)(*(uint64_t*)imgptr);
+ DDD("fmt %d dw %d dh %d userpriv %p", (int)myImg.fmt, (int)myImg.d_w,
+ (int)myImg.d_h, myImg.user_priv);
}
//TODO: we might not need to do the putting all the time
-vpx_image_t* vpx_codec_get_frame(vpx_codec_ctx_t* ctx) {
+vpx_image_t* vpx_codec_get_frame(vpx_codec_ctx_t* ctx, int hostColorBufferId) {
+ DDD("%s %d %p", __func__, __LINE__);
auto transport = GoldfishMediaTransport::getInstance();
- transport->writeParam(ctx->outputBufferWidth, 0);
- transport->writeParam(ctx->outputBufferHeight, 1);
- transport->writeParam(ctx->width, 2);
- transport->writeParam(ctx->height, 3);
- transport->writeParam(ctx->bpp, 4);
- transport->writeParam(transport->offsetOf((uint64_t)(ctx->dst)), 5);
+ transport->writeParam(ctx->id, 0, ctx->address_offset);
+ transport->writeParam(ctx->outputBufferWidth, 1, ctx->address_offset);
+ transport->writeParam(ctx->outputBufferHeight, 2, ctx->address_offset);
+ transport->writeParam(ctx->width, 3, ctx->address_offset);
+ transport->writeParam(ctx->height, 4, ctx->address_offset);
+ transport->writeParam(ctx->bpp, 5, ctx->address_offset);
+ transport->writeParam(ctx->hostColorBufferId, 6, ctx->address_offset);
+ transport->writeParam(
+ transport->offsetOf((uint64_t)(ctx->dst)) - ctx->address_offset, 7,
+ ctx->address_offset);
sendVpxOperation(ctx, MediaOperation::GetImage);
- auto* retptr = transport->getReturnAddr();
+ auto* retptr = transport->getReturnAddr(ctx->address_offset);
int ret = getReturnCode(retptr);
if (ret) {
return nullptr;
}
- getVpxFrame(retptr);
- return &myImg;
+ getVpxFrame(retptr, ctx->myImg);
+ return &(ctx->myImg);
}
int vpx_codec_flush(vpx_codec_ctx_t* ctx) {
+ DDD("%s %d", __func__, __LINE__);
+ auto transport = GoldfishMediaTransport::getInstance();
+ transport->writeParam(ctx->id, 0, ctx->address_offset);
sendVpxOperation(ctx, MediaOperation::Flush);
return 0;
}
@@ -87,12 +145,17 @@
unsigned int data_sz,
void* user_priv,
long deadline) {
+ DDD("%s %d data size %d userpriv %p", __func__, __LINE__, (int)data_sz,
+ user_priv);
auto transport = GoldfishMediaTransport::getInstance();
memcpy(ctx->data, data, data_sz);
- transport->writeParam(transport->offsetOf((uint64_t)(ctx->data)), 0);
- transport->writeParam((__u64)data_sz, 1);
- transport->writeParam((__u64)user_priv, 2);
+ transport->writeParam(ctx->id, 0, ctx->address_offset);
+ transport->writeParam(
+ transport->offsetOf((uint64_t)(ctx->data)) - ctx->address_offset, 1,
+ ctx->address_offset);
+ transport->writeParam((__u64)data_sz, 2, ctx->address_offset);
+ transport->writeParam((__u64)user_priv, 3, ctx->address_offset);
sendVpxOperation(ctx, MediaOperation::DecodeImage);
return 0;
}