|
|
|
@ -24,14 +24,6 @@ |
|
|
|
|
*/ |
|
|
|
|
const int env_debug_encoder = (getenv("DEBUG_ENCODER") != NULL) ? atoi(getenv("DEBUG_ENCODER")) : 0; |
|
|
|
|
|
|
|
|
|
static void checked_ioctl(int fd, unsigned long request, void *argp) { |
|
|
|
|
int ret = util::safe_ioctl(fd, request, argp); |
|
|
|
|
if (ret != 0) { |
|
|
|
|
LOGE("checked_ioctl failed with error %d (%d %lx %p)", errno, fd, request, argp); |
|
|
|
|
assert(0); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void dequeue_buffer(int fd, v4l2_buf_type buf_type, unsigned int *index=NULL, unsigned int *bytesused=NULL, unsigned int *flags=NULL, struct timeval *timestamp=NULL) { |
|
|
|
|
v4l2_plane plane = {0}; |
|
|
|
|
v4l2_buffer v4l_buf = { |
|
|
|
@ -40,7 +32,7 @@ static void dequeue_buffer(int fd, v4l2_buf_type buf_type, unsigned int *index=N |
|
|
|
|
.m = { .planes = &plane, }, |
|
|
|
|
.length = 1, |
|
|
|
|
}; |
|
|
|
|
checked_ioctl(fd, VIDIOC_DQBUF, &v4l_buf); |
|
|
|
|
util::safe_ioctl(fd, VIDIOC_DQBUF, &v4l_buf, "VIDIOC_DQBUF failed"); |
|
|
|
|
|
|
|
|
|
if (index) *index = v4l_buf.index; |
|
|
|
|
if (bytesused) *bytesused = v4l_buf.m.planes[0].bytesused; |
|
|
|
@ -66,8 +58,7 @@ static void queue_buffer(int fd, v4l2_buf_type buf_type, unsigned int index, Vis |
|
|
|
|
.flags = V4L2_BUF_FLAG_TIMESTAMP_COPY, |
|
|
|
|
.timestamp = timestamp |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
checked_ioctl(fd, VIDIOC_QBUF, &v4l_buf); |
|
|
|
|
util::safe_ioctl(fd, VIDIOC_QBUF, &v4l_buf, "VIDIOC_QBUF failed"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void request_buffers(int fd, v4l2_buf_type buf_type, unsigned int count) { |
|
|
|
@ -76,7 +67,7 @@ static void request_buffers(int fd, v4l2_buf_type buf_type, unsigned int count) |
|
|
|
|
.memory = V4L2_MEMORY_USERPTR, |
|
|
|
|
.count = count |
|
|
|
|
}; |
|
|
|
|
checked_ioctl(fd, VIDIOC_REQBUFS, &reqbuf); |
|
|
|
|
util::safe_ioctl(fd, VIDIOC_REQBUFS, &reqbuf, "VIDIOC_REQBUFS failed"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void V4LEncoder::dequeue_handler(V4LEncoder *e) { |
|
|
|
@ -159,7 +150,7 @@ V4LEncoder::V4LEncoder(const EncoderInfo &encoder_info, int in_width, int in_hei |
|
|
|
|
assert(fd >= 0); |
|
|
|
|
|
|
|
|
|
struct v4l2_capability cap; |
|
|
|
|
checked_ioctl(fd, VIDIOC_QUERYCAP, &cap); |
|
|
|
|
util::safe_ioctl(fd, VIDIOC_QUERYCAP, &cap, "VIDIOC_QUERYCAP failed"); |
|
|
|
|
LOGD("opened encoder device %s %s = %d", cap.driver, cap.card, fd); |
|
|
|
|
assert(strcmp((const char *)cap.driver, "msm_vidc_driver") == 0); |
|
|
|
|
assert(strcmp((const char *)cap.card, "msm_vidc_venc") == 0); |
|
|
|
@ -177,7 +168,7 @@ V4LEncoder::V4LEncoder(const EncoderInfo &encoder_info, int in_width, int in_hei |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
checked_ioctl(fd, VIDIOC_S_FMT, &fmt_out); |
|
|
|
|
util::safe_ioctl(fd, VIDIOC_S_FMT, &fmt_out, "VIDIOC_S_FMT failed"); |
|
|
|
|
|
|
|
|
|
v4l2_streamparm streamparm = { |
|
|
|
|
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, |
|
|
|
@ -191,7 +182,7 @@ V4LEncoder::V4LEncoder(const EncoderInfo &encoder_info, int in_width, int in_hei |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
checked_ioctl(fd, VIDIOC_S_PARM, &streamparm); |
|
|
|
|
util::safe_ioctl(fd, VIDIOC_S_PARM, &streamparm, "VIDIOC_S_PARM failed"); |
|
|
|
|
|
|
|
|
|
struct v4l2_format fmt_in = { |
|
|
|
|
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, |
|
|
|
@ -205,7 +196,7 @@ V4LEncoder::V4LEncoder(const EncoderInfo &encoder_info, int in_width, int in_hei |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
checked_ioctl(fd, VIDIOC_S_FMT, &fmt_in); |
|
|
|
|
util::safe_ioctl(fd, VIDIOC_S_FMT, &fmt_in, "VIDIOC_S_FMT failed"); |
|
|
|
|
|
|
|
|
|
LOGD("in buffer size %d, out buffer size %d", |
|
|
|
|
fmt_in.fmt.pix_mp.plane_fmt[0].sizeimage, |
|
|
|
@ -221,7 +212,7 @@ V4LEncoder::V4LEncoder(const EncoderInfo &encoder_info, int in_width, int in_hei |
|
|
|
|
{ .id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD, .value = 1}, |
|
|
|
|
}; |
|
|
|
|
for (auto ctrl : ctrls) { |
|
|
|
|
checked_ioctl(fd, VIDIOC_S_CTRL, &ctrl); |
|
|
|
|
util::safe_ioctl(fd, VIDIOC_S_CTRL, &ctrl, "VIDIOC_S_CTRL failed"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -234,7 +225,7 @@ V4LEncoder::V4LEncoder(const EncoderInfo &encoder_info, int in_width, int in_hei |
|
|
|
|
{ .id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES, .value = 0}, |
|
|
|
|
}; |
|
|
|
|
for (auto ctrl : ctrls) { |
|
|
|
|
checked_ioctl(fd, VIDIOC_S_CTRL, &ctrl); |
|
|
|
|
util::safe_ioctl(fd, VIDIOC_S_CTRL, &ctrl, "VIDIOC_S_CTRL failed"); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
struct v4l2_control ctrls[] = { |
|
|
|
@ -250,7 +241,7 @@ V4LEncoder::V4LEncoder(const EncoderInfo &encoder_info, int in_width, int in_hei |
|
|
|
|
{ .id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE, .value = 0}, |
|
|
|
|
}; |
|
|
|
|
for (auto ctrl : ctrls) { |
|
|
|
|
checked_ioctl(fd, VIDIOC_S_CTRL, &ctrl); |
|
|
|
|
util::safe_ioctl(fd, VIDIOC_S_CTRL, &ctrl, "VIDIOC_S_CTRL failed"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -260,9 +251,9 @@ V4LEncoder::V4LEncoder(const EncoderInfo &encoder_info, int in_width, int in_hei |
|
|
|
|
|
|
|
|
|
// start encoder
|
|
|
|
|
v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
|
|
|
|
checked_ioctl(fd, VIDIOC_STREAMON, &buf_type); |
|
|
|
|
util::safe_ioctl(fd, VIDIOC_STREAMON, &buf_type, "VIDIOC_STREAMON failed"); |
|
|
|
|
buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
|
|
|
|
checked_ioctl(fd, VIDIOC_STREAMON, &buf_type); |
|
|
|
|
util::safe_ioctl(fd, VIDIOC_STREAMON, &buf_type, "VIDIOC_STREAMON failed"); |
|
|
|
|
|
|
|
|
|
// queue up output buffers
|
|
|
|
|
for (unsigned int i = 0; i < BUF_OUT_COUNT; i++) { |
|
|
|
@ -305,7 +296,7 @@ void V4LEncoder::encoder_close() { |
|
|
|
|
for (int i = 0; i < BUF_IN_COUNT; i++) free_buf_in.push(i); |
|
|
|
|
// no frames, stop the encoder
|
|
|
|
|
struct v4l2_encoder_cmd encoder_cmd = { .cmd = V4L2_ENC_CMD_STOP }; |
|
|
|
|
checked_ioctl(fd, VIDIOC_ENCODER_CMD, &encoder_cmd); |
|
|
|
|
util::safe_ioctl(fd, VIDIOC_ENCODER_CMD, &encoder_cmd, "VIDIOC_ENCODER_CMD failed"); |
|
|
|
|
// join waits for V4L2_QCOM_BUF_FLAG_EOS
|
|
|
|
|
dequeue_handler_thread.join(); |
|
|
|
|
assert(extras.empty()); |
|
|
|
@ -316,10 +307,10 @@ void V4LEncoder::encoder_close() { |
|
|
|
|
V4LEncoder::~V4LEncoder() { |
|
|
|
|
encoder_close(); |
|
|
|
|
v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; |
|
|
|
|
checked_ioctl(fd, VIDIOC_STREAMOFF, &buf_type); |
|
|
|
|
util::safe_ioctl(fd, VIDIOC_STREAMOFF, &buf_type, "VIDIOC_STREAMOFF failed"); |
|
|
|
|
request_buffers(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 0); |
|
|
|
|
buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
|
|
|
|
checked_ioctl(fd, VIDIOC_STREAMOFF, &buf_type); |
|
|
|
|
util::safe_ioctl(fd, VIDIOC_STREAMOFF, &buf_type, "VIDIOC_STREAMOFF failed"); |
|
|
|
|
request_buffers(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 0); |
|
|
|
|
close(fd); |
|
|
|
|
|
|
|
|
|