Rockchip: fix frame hdr overwritten error
frmHdrBufLen & frmhdr might be overwritten sometimes, which
may cause "Bad address" error when set ext ctrls.
BUG=chromium:497324
TEST=screen share through Hangouts, no more "Bad address"
Change-Id: I95d355139ca78bcb9e28a7ad018f80a71c14de34
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
Previous-Reviewed-on: https://chromium-review.googlesource.com/277732
(cherry picked from commit 6727c8e5cab46de469453fb8eee3b89fbf790c4b)
Reviewed-on: https://chromium-review.googlesource.com/280952
Reviewed-by: Justin Chuang <jchuang@chromium.org>
Tested-by: Justin Chuang <jchuang@chromium.org>
diff --git a/libv4l-rockchip/libvpu/vp8_enc/encasiccontroller_v2.c b/libv4l-rockchip/libvpu/vp8_enc/encasiccontroller_v2.c
index a5a090a..74468ee 100644
--- a/libv4l-rockchip/libvpu/vp8_enc/encasiccontroller_v2.c
+++ b/libv4l-rockchip/libvpu/vp8_enc/encasiccontroller_v2.c
@@ -65,7 +65,9 @@
memset(asic->segmentMap.vir_addr, 0, asic->segmentMap.size);
- asic->frmhdr = (uint8_t*)(((int)asic->hdr + 7) & (~7));
+ /* aligned to 8 bytes. we use unsigned long here for ILP32 and LP64 */
+ asic->frmhdr = (uint8_t*)ALIGN((unsigned long)asic->hdr, 8);
+
asic->frmHdrBufLen = FRAME_HEADER_SIZE;
return ENCHW_OK;
diff --git a/libv4l-rockchip/libvpu/vp8_enc/enccommon.h b/libv4l-rockchip/libvpu/vp8_enc/enccommon.h
index dc9eeb5..aec74d4 100644
--- a/libv4l-rockchip/libvpu/vp8_enc/enccommon.h
+++ b/libv4l-rockchip/libvpu/vp8_enc/enccommon.h
@@ -40,4 +40,6 @@
#define SIGN(a) ((a) < (0) ? (-1) : (1))
#define CLIP3(v, min, max) ((v) < (min) ? (min) : ((v) > (max) ? (max) : (v)))
+#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
+
#endif
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8codeframe.c b/libv4l-rockchip/libvpu/vp8_enc/vp8codeframe.c
index 7b62b35..e649d6c 100644
--- a/libv4l-rockchip/libvpu/vp8_enc/vp8codeframe.c
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8codeframe.c
@@ -128,25 +128,28 @@
/* header remainder is byte aligned, max 7 bytes = 56 bits */
if (regs->firstFreeBit != 0) {
- /* 64-bit aligned stream pointer */
- uint8_t* pTmp = (uint8_t*)((size_t)(inst->buffer[1].data) & (uint32_t)(~0x07));
uint32_t val;
- /* Clear remaining bits */
- for (val = 6; val >= regs->firstFreeBit / 8; val--)
- pTmp[val] = 0;
+ /* firstFreeBit is less than 8 bytes, so 8 bytes is enough */
+ uint8_t buf[8];
- val = pTmp[0] << 24;
- val |= pTmp[1] << 16;
- val |= pTmp[2] << 8;
- val |= pTmp[3];
+ ASSERT(regs->firstFreeBit / 8 <= sizeof(buf));
+
+ memset(buf, 0, sizeof(buf));
+ memcpy(buf, inst->asic.frmhdr + regs->outputStrmBase,
+ regs->firstFreeBit / 8);
+
+ val = buf[0] << 24;
+ val |= buf[1] << 16;
+ val |= buf[2] << 8;
+ val |= buf[3];
regs->strmStartMSB = val; /* 32 bits to MSB */
if (regs->firstFreeBit > 32) {
- val = pTmp[4] << 24;
- val |= pTmp[5] << 16;
- val |= pTmp[6] << 8;
+ val = buf[4] << 24;
+ val |= buf[5] << 16;
+ val |= buf[6] << 8;
regs->strmStartLSB = val;
} else
diff --git a/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.c b/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.c
index a967d05..27e1049 100644
--- a/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.c
+++ b/libv4l-rockchip/libvpu/vp8_enc/vp8encapi.c
@@ -579,21 +579,20 @@
/* Divide stream buffer for every partition */
{
- uint8_t* pStart = (uint8_t*)pEncInst->asic.frmhdr;
+ uint8_t* pBuf = (uint8_t*)pEncInst->asic.frmhdr;
uint32_t bufSize = pEncInst->asic.frmHdrBufLen;
- uint8_t* pEnd;
+ uint32_t tagSize = 0;
int32_t status = ENCHW_OK;
/* Frame tag 10 bytes (I-frame) or 3 bytes (P-frame),
* written by SW at end of frame */
- pEnd = pStart + 3;
- if (ct == VP8ENC_INTRA_FRAME) pEnd += 7;
- if (VP8SetBuffer(&pEncInst->buffer[0], pStart, pEnd - pStart) == ENCHW_NOK)
+ tagSize = (ct == VP8ENC_INTRA_FRAME) ? 10 : 3;
+
+ if (VP8SetBuffer(&pEncInst->buffer[0], pBuf, tagSize) == ENCHW_NOK)
status = ENCHW_NOK;
- pStart = pEnd;
- pEnd = pStart + bufSize;
- if (VP8SetBuffer(&pEncInst->buffer[1], pStart, pEnd - pStart) == ENCHW_NOK)
+ if (VP8SetBuffer(&pEncInst->buffer[1], pBuf + tagSize,
+ bufSize - tagSize) == ENCHW_NOK)
status = ENCHW_NOK;
if (status == ENCHW_NOK) {