libvideorender: CB2 fix frame dropped [1/1]
PD#SWPL-179493
Problem:
1.pause and resume can cause frame dropped.
those frames ready to send to weston in
queue will drop when resume
2.if weston output is null, we can't set
configt on surface, it causes wayland protocol
communicate failure.
Solution:
1.do not pause in weston render plugin.
pause in render lib core.
2.refine display frame when output is null
Verify:
ap222
Change-Id: I32e8c268884e05dc8b2a590a768506afbc2f26fe
Signed-off-by: fei.deng <fei.deng@amlogic.com>
diff --git a/weston/wayland_display.cpp b/weston/wayland_display.cpp
index adf66f4..9332fba 100644
--- a/weston/wayland_display.cpp
+++ b/weston/wayland_display.cpp
@@ -1336,6 +1336,48 @@
void WaylandDisplay::displayFrameBuffer(RenderBuffer * buf, int64_t realDisplayTime)
{
+ WaylandBuffer *waylandBuf = NULL;
+ struct wl_buffer * wlbuffer = NULL;
+ int ret;
+
+ if (!buf) {
+ ERROR(mLogCategory,"Error input params, RenderBuffer is null");
+ return;
+ }
+
+ if (buf->flag & BUFFER_FLAG_DMA_BUFFER) {
+ if (buf->dma.width <=0 || buf->dma.height <=0) {
+ buf->dma.width = mVideoWidth;
+ buf->dma.height = mVideoHeight;
+ }
+
+ waylandBuf = findWaylandBuffer(buf);
+ if (waylandBuf) {
+ waylandBuf->setRenderRealTime(realDisplayTime);
+ } else {
+ ERROR(mLogCategory,"NOT found wayland buffer,please prepare buffer first");
+ goto waylandbuf_fail;
+ }
+ }
+
+ //if no wl_output, drop this buffer
+ if (mCurrentDisplayOutput->wlOutput == NULL) {
+ TRACE(mLogCategory,"No wl_output");
+ //insert this buffer to committed weston buffer manager
+ std::pair<int64_t, WaylandBuffer *> item(realDisplayTime, waylandBuf);
+ mCommittedBufferMap.insert(item);
+ mWaylandPlugin->handleFrameDropped(buf);
+ WaylandBuffer::bufferRelease(waylandBuf,NULL);
+ return;
+ }
+
+ //must commit areasurface first, because weston xdg surface maybe timeout
+ //this cause video is not display,commit can resume xdg surface
+ if (!mReCommitAreaSurface) {
+ mReCommitAreaSurface = true;
+ wl_surface_commit (mAreaSurface);
+ }
+
//set frame rate to weston,it lets weston to select suitable mode
if (mFrameRateChanged && mAmlConfigAPIList.enableSetDisplayRate) {
mFrameRateChanged = false;
@@ -1356,48 +1398,13 @@
before resolution changed and had release by weston */
cleanWaylandBufferBeforeResChanged();
}
- WaylandBuffer *waylandBuf = NULL;
- struct wl_buffer * wlbuffer = NULL;
- int ret;
-
- if (!buf) {
- ERROR(mLogCategory,"Error input params, waylandbuffer is null");
- return;
- }
-
- //must commit areasurface first, because weston xdg surface maybe timeout
- //this cause video is not display,commit can resume xdg surface
- if (!mReCommitAreaSurface) {
- mReCommitAreaSurface = true;
- wl_surface_commit (mAreaSurface);
- }
//TRACE(mLogCategory,"display renderBuffer:%p,PTS:%lld us,realtime:%lld",buf, buf->pts/1000, realDisplayTime);
- if (buf->flag & BUFFER_FLAG_DMA_BUFFER) {
- if (buf->dma.width <=0 || buf->dma.height <=0) {
- buf->dma.width = mVideoWidth;
- buf->dma.height = mVideoHeight;
- }
- waylandBuf = findWaylandBuffer(buf);
- if (waylandBuf) {
- waylandBuf->setRenderRealTime(realDisplayTime);
- } else {
- ERROR(mLogCategory,"NOT found wayland buffer,please prepare buffer first");
- goto waylandbuf_fail;
- }
- }
-
if (waylandBuf) {
wlbuffer = waylandBuf->getWlBuffer();
}
- //if no wl_output, drop this buffer
- if (mCurrentDisplayOutput->wlOutput == NULL) {
- TRACE(mLogCategory,"No wl_output");
- mWaylandPlugin->handleFrameDropped(buf);
- mWaylandPlugin->handleBufferRelease(buf);
- return;
- }
+
if (wlbuffer) {
Tls::Mutex::Autolock _l(mRenderMutex);
++mCommitCnt;
@@ -1421,7 +1428,8 @@
} else {
WARNING(mLogCategory,"wlbuffer is NULL");
/* clear both video and parent surfaces */
- cleanSurface();
+ //cleanSurface();
+ goto waylandbuf_fail;
}
wl_display_flush (mWlDisplay);
@@ -1616,6 +1624,7 @@
void WaylandDisplay::addWaylandBuffer(RenderBuffer * buf, WaylandBuffer *waylandbuf)
{
+ Tls::Mutex::Autolock _l(mBufferMutex);
if (buf->flag & BUFFER_FLAG_DMA_BUFFER) {
std::size_t hashval = calculateDmaBufferHash(buf->dma);
std::pair<std::size_t, WaylandBuffer *> item(hashval, waylandbuf);
@@ -1627,6 +1636,7 @@
WaylandBuffer* WaylandDisplay::findWaylandBuffer(RenderBuffer * buf)
{
+ Tls::Mutex::Autolock _l(mBufferMutex);
std::size_t hashval = calculateDmaBufferHash(buf->dma);
auto item = mWaylandBuffersMap.find(hashval);
if (item == mWaylandBuffersMap.end()) {
@@ -1638,6 +1648,7 @@
void WaylandDisplay::cleanAllWaylandBuffer()
{
+ Tls::Mutex::Autolock _l(mBufferMutex);
//free all obtain buff
for (auto item = mWaylandBuffersMap.begin(); item != mWaylandBuffersMap.end(); ) {
WaylandBuffer *waylandbuf = (WaylandBuffer*)item->second;
@@ -1653,6 +1664,7 @@
*/
void WaylandDisplay::cleanWaylandBufferBeforeResChanged()
{
+ Tls::Mutex::Autolock _l(mBufferMutex);
for (auto item = mWaylandBuffersMap.begin(); item != mWaylandBuffersMap.end(); ) {
WaylandBuffer *wlbuf = (WaylandBuffer*)item->second;
if (wlbuf->isFree()) {
@@ -1705,7 +1717,7 @@
}
/*cobalt is not set frame rate to gst pipeline. we set default 59.94
frame rate to weston*/
- if (mFrameRateFractionNum == 0 && mFrameRateFractionDenom == 1) {
+ if (mFrameRateFractionNum == 0) {
mFrameRateFractionNum = 59940;
mFrameRateFractionDenom = 1000;
}
diff --git a/weston/wayland_display.h b/weston/wayland_display.h
index a945ac9..9f3de50 100644
--- a/weston/wayland_display.h
+++ b/weston/wayland_display.h
@@ -106,13 +106,7 @@
{
return mShm;
};
- struct wl_output *getWlOutput()
- {
- if (mCurrentDisplayOutput) {
- return mCurrentDisplayOutput->wlOutput;
- }
- return NULL;
- };
+
/**
* @brief Set the Keep Last Frame when playback end
* #param keep 1:keep last frame, 0:do not keep
diff --git a/weston/wayland_dma.cpp b/weston/wayland_dma.cpp
index 6fe0313..0ab9e74 100644
--- a/weston/wayland_dma.cpp
+++ b/weston/wayland_dma.cpp
@@ -48,7 +48,8 @@
{
//release wl_buffer
if (mWlBuffer) {
- // TRACE(mLogCategory,"delete WaylandDmaBuffer:%p,wl_buffer:%p",this,mWlBuffer);
+ // TRACE(mLogCategory,"delete WaylandDmaBuffer:%p,wl_buffer:%p %dx%d",
+ // this,mWlBuffer,mRenderDmaBuffer.width,mRenderDmaBuffer.height);
wl_buffer_destroy(mWlBuffer);
mWlBuffer = NULL;
}
@@ -131,7 +132,7 @@
/* Request buffer creation */
zwp_linux_buffer_params_v1_add_listener (params, &dmabuf_params_listener, (void *)this);
- //TRACE(mLogCategory,"zwp_linux_buffer_params_v1_create,dma width:%d,height:%d,dmabufferformat:%d",dmabuf->width,dmabuf->height,dmabufferFormat);
+ // TRACE(mLogCategory,"zwp_linux_buffer_params_v1_create,dma width:%d,height:%d,dmabufferformat:%d",dmabuf->width,dmabuf->height,dmabufferFormat);
zwp_linux_buffer_params_v1_create (params, dmabuf->width, dmabuf->height, dmabufferFormat, flags);
/* Wait for the request answer */
diff --git a/weston/wayland_plugin.cpp b/weston/wayland_plugin.cpp
index dc41c9f..5523520 100644
--- a/weston/wayland_plugin.cpp
+++ b/weston/wayland_plugin.cpp
@@ -156,12 +156,15 @@
int WaylandPlugin::pause()
{
- mPaused = true;
+ /*pause and resume can cause frame dropped.
+ those frames ready to send to weston in queue will drop
+ when resume*/
+ //mPaused = true;
return NO_ERROR;
}
int WaylandPlugin::resume()
{
- mPaused = false;
+ //mPaused = false;
return NO_ERROR;
}
@@ -301,13 +304,6 @@
goto tag_next;
}
- //if weston has no wl_outout,it means weston can't display frames
- //so we should display buffer to display to drop buffers
- if (mDisplay->getWlOutput() == NULL) {
- mQueue->pop((void **)&expiredFrameEntity);
- goto tag_post;
- }
-
//if weston obtains a buffer rendering,we can't send buffer to weston
if (mDisplay->isRedrawingPending()) {
goto tag_next;