decode directly to NV12 with the correct stride without using the hw rotator

sync
pencilpusher 2 weeks ago committed by GitHub
parent 7455dde790
commit 276bc77d4a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 53
      tools/replay/qcom/decoder.cc
  2. 9
      tools/replay/qcom/decoder.h

@ -8,6 +8,14 @@
#include "common/swaglog.h"
#include "common/util.h"
// echo "0xFFFF" > /sys/kernel/debug/msm_vidc/debug_level
static void copyBuffer(VisionBuf *src_buf, VisionBuf *dst_buf) {
// Copy Y plane
memcpy(dst_buf->y, src_buf->y, src_buf->height * src_buf->stride);
// Copy UV plane
memcpy(dst_buf->uv, src_buf->uv, src_buf->height / 2 * src_buf->stride);
}
static void request_buffers(int fd, v4l2_buf_type buf_type, unsigned int count) {
struct v4l2_requestbuffers reqbuf = {
@ -44,8 +52,7 @@ bool MsmVidc::init(const char* dev, size_t width, size_t height, uint64_t codec)
util::safe_ioctl(fd, VIDIOC_STREAMON, &out_type, "VIDIOC_STREAMON OUTPUT failed");
restartCapture();
setupPolling();
rotator.init();
rotator.configUBWCtoNV12(width, height);
this->initialized = true;
return true;
}
@ -117,25 +124,13 @@ VisionBuf* MsmVidc::handleCapture() {
buf.length = 1;
util::safe_ioctl(this->fd, VIDIOC_DQBUF, &buf, "VIDIOC_DQBUF CAPTURE failed");
if (buf.m.planes[0].bytesused) {
static size_t cap_cnt = 0;
cap_cnt++;
if (cap_cnt % 240 == 0) {
LOGD("Dequeued %zu capture buffers", cap_cnt);
if (this->reconfigure_pending || buf.m.planes[0].bytesused == 0) {
return nullptr;
}
if (!this->reconfigure_pending) {
rotator.putFrame(&cap_bufs[buf.index]);
VisionBuf *rotated = rotator.getFrame(100);
copyBuffer(&cap_bufs[buf.index], this->current_output_buf);
queueCaptureBuffer(buf.index);
if (rotated) {
rotator.convertStride(rotated, this->current_output_buf);
return this->current_output_buf;
}
}
} else {
LOGE("Dequeued empty capture buffer %d", buf.index);
}
return nullptr;
}
bool MsmVidc::subscribeEvents() {
@ -149,12 +144,16 @@ bool MsmVidc::subscribeEvents() {
bool MsmVidc::setPlaneFormat(enum v4l2_buf_type type, uint32_t fourcc) {
struct v4l2_format fmt = {.type = type};
struct v4l2_pix_format_mplane *pix = &fmt.fmt.pix_mp;
*pix = { .width = (__u32)this->w, .height = (__u32)this->h, .pixelformat = fourcc };
*pix = {
.width = (__u32)this->w,
.height = (__u32)this->h,
.pixelformat = fourcc
};
util::safe_ioctl(fd, VIDIOC_S_FMT, &fmt, "VIDIOC_S_FMT failed");
if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
this->out_buf_size = pix->plane_fmt[0].sizeimage;
int ion_size = this->out_buf_size * OUTPUT_BUFFER_COUNT; // Output (input) buffers are ION buffer.
this->out_buf.allocate_no_cache(ion_size); // mmap rw
this->out_buf.allocate(ion_size); // mmap rw
for (int i = 0; i < OUTPUT_BUFFER_COUNT; i++) {
this->out_buf_off[i] = i * this->out_buf_size;
this->out_buf_addr[i] = (char *)this->out_buf.addr + this->out_buf_off[i];
@ -164,11 +163,15 @@ bool MsmVidc::setPlaneFormat(enum v4l2_buf_type type, uint32_t fourcc) {
} else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
request_buffers(this->fd, type, CAPTURE_BUFFER_COUNT);
util::safe_ioctl(fd, VIDIOC_G_FMT, &fmt, "VIDIOC_G_FMT failed");
const __u32 y_size = pix->plane_fmt[0].sizeimage;
const __u32 y_stride = pix->plane_fmt[0].bytesperline;
for (int i = 0; i < CAPTURE_BUFFER_COUNT; i++) {
this->cap_bufs[i].allocate_no_cache(pix->plane_fmt[0].sizeimage);
this->cap_bufs[i].init_yuv(pix->width, pix->height, pix->plane_fmt[0].bytesperline, 0);
size_t uv_offset = (size_t)y_stride * pix->height;
size_t required = uv_offset + (y_stride * pix->height / 2); // enough for Y + UV. For linear NV12, UV plane starts at y_stride * height.
size_t alloc_size = std::max<size_t>(y_size, required);
this->cap_bufs[i].allocate(alloc_size);
this->cap_bufs[i].init_yuv(pix->width, pix->height, y_stride, uv_offset);
}
this->cap_buf_format = pix->pixelformat;
LOGD("Set capture buffer size to %d, count %d, addr %p, extradata size %d",
pix->plane_fmt[0].sizeimage, CAPTURE_BUFFER_COUNT, this->cap_bufs[0].addr, pix->plane_fmt[1].sizeimage);
}
@ -201,7 +204,7 @@ bool MsmVidc::restartCapture() {
}
// setup, start and queue capture buffers
setDBP();
setPlaneFormat(type, V4L2_PIX_FMT_NV12_UBWC);
setPlaneFormat(type, V4L2_PIX_FMT_NV12);
util::safe_ioctl(this->fd, VIDIOC_STREAMON, &type, "VIDIOC_STREAMON CAPTURE failed");
for (size_t i = 0; i < CAPTURE_BUFFER_COUNT; ++i) {
queueCaptureBuffer(i);
@ -259,7 +262,7 @@ bool MsmVidc::setDBP() {
struct v4l2_ext_control control[2] = {0};
struct v4l2_ext_controls controls = {0};
control[0].id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
control[0].value = 0; // V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY
control[0].value = 1; // V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY
control[1].id = V4L2_CID_MPEG_VIDC_VIDEO_DPB_COLOR_FORMAT;
control[1].value = 0; // V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE
controls.count = 2;

@ -1,6 +1,9 @@
#pragma once
#include "sde_rotator.h"
#include <linux/videodev2.h>
#include <poll.h>
#include "msgq/visionipc/visionbuf.h"
#include "third_party/linux/include/media/msm_vidc.h"
extern "C" {
@ -59,8 +62,6 @@ private:
bool out_buf_flag[OUTPUT_BUFFER_COUNT] = {false};
const int out_buf_cnt = OUTPUT_BUFFER_COUNT;
uint32_t cap_buf_format = 0;
const int subscriptions[2] = {
V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT
@ -87,6 +88,4 @@ private:
int handleSignal();
bool handleOutput();
bool handleEvent();
SdeRotator rotator;
};

Loading…
Cancel
Save