==================================== Motion Vector with the H.264 Encoder ==================================== Astra SDK scarthgap_6.12_v2.2.0 adds support for accessing motion vectors from the H.264 encoder used by SL1640 and SL1680. The ``vpu`` driver adds a new control ``SYNA_V4L2_CID_VENC_ENABLE_METADATA_MV`` which can be set to enable motion vector data. https://github.com/synaptics-astra/linux_6_12-drivers-synaptics/commit/fd6bca6bf70637aa267d2d36159f05ecfa97a979 This example sets the V4L2 Control ID and Value:: ctrl.id = SYNA_V4L2_CID_VENC_ENABLE_METADATA_MV; ctrl.value = true; dbg("setting (%d): %u", id, ctrl.value); ret = ::ioctl(mFd, VIDIOC_S_CTRL, &ctrl); Motion Vector Data can be accessed from the capture buffer:: v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = ::ioctrl(mFd, VIDIOC_DQBUF, &v4l2_buf); v4l2_buf plane[0]: encoded ES data v4l2_buf plane[1]: motion vector data This example prints the Motion Vector data to a file:: int write_motion_vector(void *mv, /* plane[1] address */ size_t size, /* plane[1]payload */ uint32_t frameIdx, /* v4l2_buf sequence */ uint32_t width, uint32_t height) { uint32_t i; uint32_t mbPerRow = (width + 15) / 16; uint32_t mbPerCol = (height + 15) / 16; uint32_t mbPerFrame = mbPerRow * mbPerCol; MVInfo_t *mbInfo = (MVInfo_t *)mv; if (!mFp || !mv) return 0; /* Print motion vector for every macroblock. */ fprintf(mFp, "\npic=%d MV full-pixel X,Y " "for %d macroblocks (%dx%d) block=0\n", frameIdx, mbPerFrame, mbPerRow, mbPerCol); for (i = 0; i < mbPerFrame; i++) { uint32_t mb_type = mbInfo[i].mbType; uint32_t mb_y = i / mbPerRow; uint32_t mb_x = i % mbPerRow; uint32_t sx = mb_x * 16; uint32_t sy = mb_y * 16; fprintf(mFp, " MBxy:(%3d,%3d) Type:%8s ", sx, sy, mbModetostr(mb_type)); if (mb_type == 6) { // P16x16 fprintf(mFp, "MV(%3d,%3d )[%21s]", mbInfo[i].mvX[0], mbInfo[i].mvY[0], " "); } else if (mb_type == 7 || mb_type == 8) { // P16x8, P8x16 fprintf(mFp, "MV(%3d,%3d ", mbInfo[i].mvX[0], mbInfo[i].mvY[0]); fprintf(mFp, "%3d,%3d) [%13s]", mbInfo[i].mvX[1], mbInfo[i].mvY[1], " "); } else if (mb_type == 9) { // P8x8 fprintf(mFp, "MV(%3d,%3d ", mbInfo[i].mvX[0], mbInfo[i].mvY[0]); fprintf(mFp, "%3d,%3d ", mbInfo[i].mvX[1], mbInfo[i].mvY[1]); fprintf(mFp, "%3d,%3d ", mbInfo[i].mvX[2], mbInfo[i].mvY[2]); fprintf(mFp, "%3d,%3d)", mbInfo[i].mvX[3], mbInfo[i].mvY[3]); } else { fprintf(mFp, "MV[%31s]", " "); } if ((i % mbPerRow) == mbPerRow-1) fprintf(mFp, "\n"); } fflush(mFp); return 0; }