/* * Copyright (C) 2025 Amlogic Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "mesonvideocompositor_plugin.h" #include "Logger.h" #include "video_tunnel.h" #include "ErrorCode.h" #define TAG "rlib:mesonvideocompositor_plugin" MesonVideoCompositorPlugin::MesonVideoCompositorPlugin(int logCategory) : mDisplayLock("displaylock"), mLogCategory(logCategory), mRenderLock("renderlock") { mWinRect.x = 0; mWinRect.y = 0; mWinRect.w = 0; mWinRect.h = 0; mMesonVideoCompositor = new MesonVideoCompositorImpl(this,logCategory); } MesonVideoCompositorPlugin::~MesonVideoCompositorPlugin() { if (mMesonVideoCompositor) { delete mMesonVideoCompositor; mMesonVideoCompositor = NULL; } } void MesonVideoCompositorPlugin::init() { INFO(mLogCategory,"\n--------------------------------\n" "plugin : MesonVideoCompositor\n" "ARCH : %s\n" "branch name : %s\n" "git version : %s\n" "change id : %s \n" "ID : %s \n" "last changed: %s\n" "build-time : %s\n" "build-name : %s\n" "level : /tmp \n" "--------------------------------\n", #if defined(__aarch64__) "arm64", #else "arm", #endif BRANCH_NAME, GIT_VERSION, COMMIT_CHANGEID, COMMIT_PD, LAST_CHANGED, BUILD_TIME, BUILD_NAME ); mMesonVideoCompositor->init(); } void MesonVideoCompositorPlugin::release() { mMesonVideoCompositor->release(); } void MesonVideoCompositorPlugin::setCallback(void *userData, PluginCallback *callback) { mUserData = userData; mCallback = callback; } int MesonVideoCompositorPlugin::openDisplay() { DEBUG(mLogCategory,"openDisplay"); return NO_ERROR; } int MesonVideoCompositorPlugin::openWindow() { DEBUG(mLogCategory,"in"); mMesonVideoCompositor->connect(); DEBUG(mLogCategory,"out"); return NO_ERROR; } int MesonVideoCompositorPlugin::prepareFrame(RenderBuffer *buffer) { return NO_ERROR; } int MesonVideoCompositorPlugin::displayFrame(RenderBuffer *buffer, int64_t displayTime) { mMesonVideoCompositor->displayFrame(buffer, displayTime); return NO_ERROR; } int MesonVideoCompositorPlugin::flush() { mMesonVideoCompositor->flush(); return NO_ERROR; } int MesonVideoCompositorPlugin::pause() { return NO_ERROR; } int MesonVideoCompositorPlugin::resume() { return NO_ERROR; } int MesonVideoCompositorPlugin::closeDisplay() { return NO_ERROR; } int MesonVideoCompositorPlugin::closeWindow() { DEBUG(mLogCategory,"in"); mMesonVideoCompositor->disconnect(); DEBUG(mLogCategory,"out"); return NO_ERROR; } int MesonVideoCompositorPlugin::getValue(PluginKey key, void *value) { switch (key) { case PLUGIN_KEY_VIDEOTUNNEL_ID: { mMesonVideoCompositor->getVideotunnelId((int *)value); } break; } return NO_ERROR; } int MesonVideoCompositorPlugin::setValue(PluginKey key, void *value) { switch (key) { case PLUGIN_KEY_WINDOW_SIZE: { RenderRect* rect = static_cast(value); mWinRect.x = rect->x; mWinRect.y = rect->y; mWinRect.w = rect->w; mWinRect.h = rect->h; mMesonVideoCompositor->setWindow(mWinRect); } break; case PLUGIN_KEY_FRAME_SIZE: { RenderFrameSize * frameSize = static_cast(value); mMesonVideoCompositor->setFrameSize(frameSize->width, frameSize->height); } break; case PLUGIN_KEY_VIDEO_FORMAT: { int videoFormat = *(int *)(value); INFO(mLogCategory,"Set video format :%d",videoFormat); } break; case PLUGIN_KEY_VIDEO_PIP: { int pip = *(int *) (value); if (pip > 0) { INFO(mLogCategory,"Set pip:%d",pip); mMesonVideoCompositor->setPip(pip); } } break; case PLUGIN_KEY_IMMEDIATELY_OUTPUT: { bool immediately = (*(int *)(value)) > 0? true: false; INFO(mLogCategory, "Set immediately output:%d",immediately); mMesonVideoCompositor->setImmediatelyOutout(immediately); } break; case PLUGIN_KEY_HIDE_VIDEO: { bool hide = (*(int *)(value)) > 0? true: false; INFO(mLogCategory, "Set hide video:%d",hide); mMesonVideoCompositor->setHideVideo(hide); } break; case PLUGIN_KEY_KEEP_LAST_FRAME: { bool keepLastFrame = (*(int *)(value)) > 0? true: false; INFO(mLogCategory, "Set keep last frame:%d",keepLastFrame); mMesonVideoCompositor->setKeepLastFrame(keepLastFrame); } break; case PLUGIN_KEY_SELECT_DISPLAY_OUTPUT: { int outputIndex = *(int *)(value); INFO(mLogCategory,"Set select display output :%d",outputIndex); mMesonVideoCompositor->setDisplayOutput(outputIndex); } break; case PLUGIN_KEY_ZORDER: { int zorder = *(int *)(value); INFO(mLogCategory,"Set zorder:%d",zorder); mMesonVideoCompositor->setZorder(zorder); } break; case PLUGIN_KEY_PIXEL_ASPECT_RATIO: { double ratio = *(double *)(value); INFO(mLogCategory,"pixel aspect ratio :%f",ratio); mMesonVideoCompositor->setPixelAspectRatio((double)ratio); } break; } return NO_ERROR; } int MesonVideoCompositorPlugin::unexpectReleaseFrame(RenderBuffer *buffer) { return NO_ERROR; } void MesonVideoCompositorPlugin::handleBufferRelease(RenderBuffer *buffer) { if (mCallback) { mCallback->doBufferReleaseCallback(mUserData, (void *)buffer); } } void MesonVideoCompositorPlugin::handleFrameDisplayed(RenderBuffer *buffer) { if (mCallback) { mCallback->doBufferDisplayedCallback(mUserData, (void *)buffer); } } void MesonVideoCompositorPlugin::handleFrameDropped(RenderBuffer *buffer) { if (mCallback) { mCallback->doBufferDroppedCallback(mUserData, (void *)buffer); } } void MesonVideoCompositorPlugin::handleMsgNotify(int type, void *detail) { if (mCallback) { mCallback->doMsgCallback(mUserData, type, detail); } } void *makePluginInstance(int id) { int fd= -1; const char *levelPath = "/tmp/rlib_plugin_level"; int category =ALogger_init(id); char *env = getenv("VIDEO_RENDER_PLUGIN_LOG_LEVEL"); if (env) { int level = atoi(env); ALogger_set_level(level); INFO(category,"env set VIDEO_RENDER_PLUGIN_LOG_LEVEL=%d",level); } //get log level from /tmp/rlib_plugin_level fd= open(levelPath, O_RDONLY|O_CLOEXEC); if ( fd >= 0 ) { char valstr[64]; uint32_t val= 0; int nRead; memset(valstr, 0, sizeof(valstr)); nRead = read(fd, valstr, sizeof(valstr) - 1); valstr[strlen(valstr)] = '\0'; if (sscanf(valstr, "%u", &val) > 0) { ALogger_set_level(val); INFO(category,"set VIDEO_RENDER_LOG_LEVEL=%d",val); } close(fd); fd = -1; } MesonVideoCompositorPlugin *plugin = new MesonVideoCompositorPlugin(category); return static_cast(plugin); } void destroyPluginInstance(void * plugin) { int category; MesonVideoCompositorPlugin *pluginInstance = static_cast(plugin); category = pluginInstance->getLogCategory(); delete pluginInstance; ALogger_exit(category); }