libvideorender: CF2 add keep last frame for weston [1/1]
PD#TV-114757
Problem:
open source code of weston don't keep last frame when
playback end
Solution:
1.add aml config api for weston
2.add keep last frame feature
Verify:
ap222
Change-Id: I8368d5395160c8e4a0803bd9e21a7f85ef002985
Signed-off-by: fei.deng <fei.deng@amlogic.com>
diff --git a/weston/Makefile b/weston/Makefile
index 4065490..fc9e286 100644
--- a/weston/Makefile
+++ b/weston/Makefile
@@ -60,7 +60,9 @@
$(PROTOCOL_PATH)/simpleshell-server-protocol.h \
$(PROTOCOL_PATH)/wayland-client-protocol.h \
$(PROTOCOL_PATH)/weston-direct-display-protocol.c \
- $(PROTOCOL_PATH)/weston-direct-display-client-protocol.h
+ $(PROTOCOL_PATH)/weston-direct-display-client-protocol.h \
+ $(PROTOCOL_PATH)/aml-config-protocol.c \
+ $(PROTOCOL_PATH)/aml-config-client-protocol.h
OBJ_WESTON_DISPLAY = \
wayland_display.o \
diff --git a/weston/wayland-protocol/aml-config.xml b/weston/wayland-protocol/aml-config.xml
new file mode 100644
index 0000000..96293c6
--- /dev/null
+++ b/weston/wayland-protocol/aml-config.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="aml_config">
+
+ <copyright>
+ Copyright © 2019 Collabora Ltd.
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice (including the next
+ paragraph) shall be included in all copies or substantial portions of the
+ Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ </copyright>
+
+ <interface name="aml_config" version="1">
+ <description summary="aml config for client">
+ Weston extension to inform the clients of the new interface added by amlogic.
+ </description>
+
+ <request name="destroy" type="destructor">
+ <description summary="destroy factory object">
+ Destroys the factory object, but does not affect any other objects.
+ </description>
+ </request>
+
+ <event name="aml_config_list">
+ <description summary="aml config list">
+ The aml_config_list event inform the clients of the new interface add by amlogic
+ </description>
+ <arg name="list" type="string"
+ summary="the new interface added by amlogic"/>
+ </event>
+ </interface>
+</protocol>
diff --git a/weston/wayland-protocol/wayland.xml b/weston/wayland-protocol/wayland.xml
index ed7b151..e5f4730 100644
--- a/weston/wayland-protocol/wayland.xml
+++ b/weston/wayland-protocol/wayland.xml
@@ -414,13 +414,11 @@
optimization for GL(ES) compositors with wl_shm clients.
</description>
</event>
- <!--
<event name="drop">
<description summary="compositor drop buffer">
Sent when this wl_buffer is dropped by the compositor.
</description>
</event>
- -->
</interface>
<interface name="wl_data_offer" version="3">
@@ -1694,6 +1692,15 @@
<arg name="pts_hi" type="uint" summary="high 32 bits of frame pts"/>
<arg name="pts_lo" type="uint" summary="low 32 bits of frame pts"/>
</request>
+ <request name="keep_last_frame">
+ <description summary="keep last frame or not">
+ This request sets a value for current surface.
+ The value is uesd to inform server to keep the last frame or not for
+ current surface when the video is over. The value will not change until
+ next different value is committed.
+ </description>
+ <arg name="keep_last_frame" type="uint" summary="keep last frame or not"/>
+ </request>
</interface>
<interface name="wl_seat" version="7">
diff --git a/weston/wayland_buffer.cpp b/weston/wayland_buffer.cpp
index 3ccdb78..fc17408 100644
--- a/weston/wayland_buffer.cpp
+++ b/weston/wayland_buffer.cpp
@@ -91,13 +91,14 @@
}
}
-//static const struct wl_buffer_listener buffer_listener = {
-// WaylandBuffer::bufferRelease,
-// WaylandBuffer::bufferdroped
-//};
- static const struct wl_buffer_listener buffer_listener = {
- WaylandBuffer::bufferRelease
- };
+static const struct wl_buffer_listener buffer_with_drop_listener = {
+ WaylandBuffer::bufferRelease,
+ WaylandBuffer::bufferdroped,
+};
+
+static const struct wl_buffer_listener buffer_listener = {
+ WaylandBuffer::bufferRelease
+};
/*if we commit buffers to weston too fast,it causes weston can't invoke this callback*/
void WaylandBuffer::frameDisplayedCallback(void *data, struct wl_callback *callback, uint32_t time)
@@ -121,6 +122,7 @@
int WaylandBuffer::constructWlBuffer(RenderBuffer *buf)
{
struct wl_buffer * wlbuffer = NULL;
+ WaylandDisplay::AmlConfigAPIList *amlConfigAPI = mDisplay->getAmlConfigAPIList();
mRenderBuffer = buf;
if (mWaylandWlWrap) {
@@ -141,7 +143,11 @@
}
/*register buffer release listen*/
- wl_buffer_add_listener (wlbuffer, &buffer_listener, this);
+ if (amlConfigAPI->enableDropFrame) {
+ wl_buffer_add_listener (wlbuffer, &buffer_with_drop_listener, this);
+ } else {
+ wl_buffer_add_listener (wlbuffer, &buffer_listener, this);
+ }
return NO_ERROR;
}
diff --git a/weston/wayland_display.cpp b/weston/wayland_display.cpp
index 36f2583..90a1608 100644
--- a/weston/wayland_display.cpp
+++ b/weston/wayland_display.cpp
@@ -179,6 +179,7 @@
}
}
+//aml weston always add crtcIndex in callbacks.
static const struct wl_output_listener outputListener = {
WaylandDisplay::outputHandleGeometry,
WaylandDisplay::outputHandleMode,
@@ -451,6 +452,33 @@
WaylandDisplay::handleXdgSurfaceConfigure,
};
+void WaylandDisplay::amlConfigure(void *data, struct aml_config *config, const char *list) {
+ WaylandDisplay *self = static_cast<WaylandDisplay *>(data);
+ TRACE(self->mLogCategory,"aml_config:%s",list);
+ if (list && strlen(list) > 0) {
+ if (strstr(list, "set_video_plane")) {
+ TRACE(self->mLogCategory,"weston enable set_video_plane");
+ self->mAmlConfigAPIList.enableSetVideoPlane = true;
+ }
+ if (strstr(list, "set_pts")) {
+ TRACE(self->mLogCategory,"weston enable set_pts");
+ self->mAmlConfigAPIList.enableSetPts = true;
+ }
+ if (strstr(list, "drop")) {
+ TRACE(self->mLogCategory,"weston enable drop");
+ self->mAmlConfigAPIList.enableDropFrame = true;
+ }
+ if (strstr(list, "keep_last_frame")) {
+ TRACE(self->mLogCategory,"weston enable keep_last_frame");
+ self->mAmlConfigAPIList.enableKeepLastFrame = true;
+ }
+ }
+}
+
+static const struct aml_config_listener aml_config_listener = {
+ WaylandDisplay::amlConfigure,
+};
+
void
WaylandDisplay::registryHandleGlobal (void *data, struct wl_registry *registry,
uint32_t name, const char *interface, uint32_t version)
@@ -522,6 +550,9 @@
//wl_seat_add_listener(self->mSeat, &seat_listener, (void *)self);
} else if (strcmp(interface, "weston_direct_display_v1") == 0) {
self->mDirect_display = (struct weston_direct_display_v1 *)wl_registry_bind(registry,name, &weston_direct_display_v1_interface, 1);
+ } else if (strcmp(interface, "aml_config") == 0) {
+ self->mAmlConfig = (struct aml_config*)wl_registry_bind(registry, name, &aml_config_interface, 1);
+ aml_config_add_listener(self->mAmlConfig, &aml_config_listener, (void *)self);
}
}
@@ -602,7 +633,6 @@
mNoBorderUpdate = false;
mAreaShmBuffer = NULL;
mCommitCnt = 0;
- mIsSendPtsToWeston = false;
mReCommitAreaSurface = false;
mAreaSurface = NULL;
mAreaSurfaceWrapper = NULL;
@@ -610,35 +640,20 @@
mVideoSubSurface = NULL;
mXdgSurfaceConfigured = false;
mPip = 0;
- mIsSendVideoPlaneId = true;
mCurrentDisplayOutput = &mOutput[0];
mUpdateRenderRectangle = false;
memset(&mRenderRect, 0, sizeof(struct Rectangle));
memset(&mVideoRect, 0, sizeof(struct Rectangle));
memset(&mWindowRect, 0, sizeof(struct Rectangle));
mFullScreen = true; //default is full screen
- char *env = getenv("VIDEO_RENDER_SEND_PTS_TO_WESTON");
- if (env) {
- int isSet = atoi(env);
- if (isSet > 0) {
- mIsSendPtsToWeston = true;
- INFO(mLogCategory,"set send pts to weston");
- } else {
- mIsSendPtsToWeston = false;
- INFO(mLogCategory,"do not send pts to weston");
- }
- }
- env = getenv("VIDEO_RENDER_SEND_VIDEO_PLANE_ID_TO_WESTON");
- if (env) {
- int isSet = atoi(env);
- if (isSet == 0) {
- mIsSendVideoPlaneId = false;
- INFO(mLogCategory,"do not send video plane id to weston");
- } else {
- mIsSendVideoPlaneId = true;
- INFO(mLogCategory,"send video plane id to weston");
- }
- }
+ mAmlConfig = NULL;
+ mKeepLastFrame = 0; //default is off keep last frame
+ //weston config private api
+ mAmlConfigAPIList.enableDropFrame = false;
+ mAmlConfigAPIList.enableKeepLastFrame = false;
+ mAmlConfigAPIList.enableSetPts = false;
+ mAmlConfigAPIList.enableSetVideoPlane = false;
+
for (int i = 0; i < DEFAULT_DISPLAY_OUTPUT_NUM; i++) {
mOutput[i].wlOutput = NULL;
mOutput[i].offsetX = 0;
@@ -722,11 +737,15 @@
createXdgShellWindowSurface();
//config weston video plane
- if (mIsSendVideoPlaneId) {
+ if (mAmlConfigAPIList.enableSetVideoPlane) {
INFO(mLogCategory,"set weston video plane:%d",mPip);
wl_surface_set_video_plane(mVideoSurfaceWrapper, mPip);
}
+ if (mKeepLastFrame) {
+ setKeepLastFrame(mKeepLastFrame);
+ }
+
//run wl display queue dispatch
DEBUG(mLogCategory,"To run wl display dispatch queue");
run("display queue");
@@ -786,6 +805,11 @@
mWlDisplayWrapper = NULL;
}
+ if (mAmlConfig) {
+ aml_config_destroy(mAmlConfig);
+ mAmlConfig = NULL;
+ }
+
if (mWlQueue) {
wl_event_queue_destroy (mWlQueue);
mWlQueue = NULL;
@@ -1291,7 +1315,7 @@
TRACE(mLogCategory,"++attach,renderbuf:%p,wl_buffer:%p(0,0,%d,%d),pts:%lld,commitCnt:%d",buf,wlbuffer,mVideoRect.w,mVideoRect.h,buf->pts,mCommitCnt);
waylandBuf->attach(mVideoSurfaceWrapper);
- if (mIsSendPtsToWeston) {
+ if (mAmlConfigAPIList.enableSetPts) {
TRACE(mLogCategory,"display time:%lld,hiPts:%u,lowPts:%u",realDisplayTime, hiPts, lowPts);
wl_surface_set_pts(mVideoSurfaceWrapper, hiPts, lowPts);
}
@@ -1550,4 +1574,13 @@
wl_surface_commit (mVideoSurfaceWrapper);
wl_surface_attach (mAreaSurfaceWrapper, NULL, 0, 0);
wl_surface_commit (mAreaSurfaceWrapper);
+}
+
+void WaylandDisplay::setKeepLastFrame(int keep)
+{
+ mKeepLastFrame = keep;
+ if (mVideoSurfaceWrapper && mAmlConfigAPIList.enableKeepLastFrame) {
+ INFO(mLogCategory,"keep last frame:%d",keep);
+ wl_surface_keep_last_frame(mVideoSurfaceWrapper, keep);
+ }
}
\ No newline at end of file
diff --git a/weston/wayland_display.h b/weston/wayland_display.h
index 300bcfc..de07fcd 100644
--- a/weston/wayland_display.h
+++ b/weston/wayland_display.h
@@ -29,6 +29,7 @@
#include "linux-explicit-synchronization-unstable-v1-client-protocol.h"
#include "viewporter-client-protocol.h"
#include "weston-direct-display-client-protocol.h"
+#include "aml-config-client-protocol.h"
#include "wayland-cursor.h"
#include "Thread.h"
#include "Poll.h"
@@ -44,6 +45,13 @@
class WaylandDisplay : public Tls::Thread{
public:
+ typedef struct {
+ bool enableSetVideoPlane;
+ bool enableSetPts;
+ bool enableDropFrame;
+ bool enableKeepLastFrame;
+ } AmlConfigAPIList;
+
WaylandDisplay(WaylandPlugin *plugin, int logCategory);
virtual ~WaylandDisplay();
/**
@@ -103,6 +111,15 @@
return NULL;
};
/**
+ * @brief Set the Keep Last Frame when playback end
+ * #param keep 1:keep last frame, 0:do not keep
+ */
+ void setKeepLastFrame(int keep);
+ AmlConfigAPIList *getAmlConfigAPIList()
+ {
+ return &mAmlConfigAPIList;
+ };
+ /**
* @brief Set the Select Display Output index
*
* @param output selected display output index
@@ -129,10 +146,6 @@
*/
void setPip(int pip);
- bool isSentPtsToWeston() {
- return mIsSendPtsToWeston;
- }
-
void setRedrawingPending(bool val) {
mRedrawingPending = val;
};
@@ -229,6 +242,7 @@
static void handleXdgToplevelConfigure (void *data, struct xdg_toplevel *xdg_toplevel,
int32_t width, int32_t height, struct wl_array *states);
static void handleXdgSurfaceConfigure (void *data, struct xdg_surface *xdg_surface, uint32_t serial);
+ static void amlConfigure(void *data, struct aml_config *config, const char *list);
private:
typedef struct DisplayOutput {
struct wl_output *wlOutput;
@@ -277,6 +291,7 @@
struct wl_touch *mTouch;
struct wl_keyboard *mKeyboard;
struct weston_direct_display_v1 *mDirect_display;
+ struct aml_config *mAmlConfig;
/*primary output will signal first,so 0 index is primary wl_output, 1 index is extend wl_output*/
DisplayOutput mOutput[DEFAULT_DISPLAY_OUTPUT_NUM]; //info about wl_output
@@ -311,8 +326,6 @@
Tls::Mutex mConfigureMutex;
bool mFullScreen; //default full screen
- bool mIsSendPtsToWeston;
-
bool mReCommitAreaSurface;
bool mUpdateRenderRectangle;
@@ -341,8 +354,9 @@
std::unordered_map<int64_t, WaylandBuffer *> mCommittedBufferMap;
int mPip; //pip video, 1->pip, 0: main video(default)
- bool mIsSendVideoPlaneId; //default true,otherwise false if set
bool mRedrawingPending;//it will be true when weston obtains a buffer rendering,otherwise false when rendered
+ AmlConfigAPIList mAmlConfigAPIList;
+ int mKeepLastFrame; //keep last frame when playback end
};
#endif /*__WAYLAND_DISPLAY_H__*/
\ No newline at end of file
diff --git a/weston/wayland_plugin.cpp b/weston/wayland_plugin.cpp
index 37fcace..015b07a 100644
--- a/weston/wayland_plugin.cpp
+++ b/weston/wayland_plugin.cpp
@@ -104,7 +104,8 @@
* we should create a post buffer thread to
* send buffer by mono time
*/
- if (!mDisplay->isSentPtsToWeston()) {
+ WaylandDisplay::AmlConfigAPIList *amlconfig = mDisplay->getAmlConfigAPIList();
+ if (!amlconfig->enableSetPts) {
DEBUG(mLogCategory,"run frame post thread");
setThreadPriority(50);
run("waylandPostThread");
@@ -124,10 +125,11 @@
* push buffer to queue, the buffer will send to
* weston in post thread
*/
- if (!mDisplay->isSentPtsToWeston()) {
+ WaylandDisplay::AmlConfigAPIList *amlconfig = mDisplay->getAmlConfigAPIList();
+ if (!amlconfig->enableSetPts) {
buffer->time = displayTime;
mQueue->push(buffer);
- DEBUG(mLogCategory,"queue size:%d",mQueue->getCnt());
+ DEBUG(mLogCategory,"queue size:%d",mQueue->getCnt());
} else {
mDisplay->displayFrameBuffer(buffer, displayTime);
}
@@ -233,6 +235,11 @@
bool mImmediatelyOutput = (*(int *)(value)) > 0? true: false;
DEBUG(mLogCategory, "Set immediately output:%d",mImmediatelyOutput);
} break;
+ case PLUGIN_KEY_KEEP_LAST_FRAME: {
+ int keep = *(int *) (value);
+ DEBUG(mLogCategory, "Set keep last frame:%d",keep);
+ mDisplay->setKeepLastFrame(keep);
+ } break;
}
return 0;
}