aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDikshita Agarwal <dikshita@codeaurora.org>2020-02-21 13:30:12 +0530
committerStanimir Varbanov <stanimir.varbanov@linaro.org>2020-05-06 14:02:48 +0300
commitb3f49cc2e1840a642dbe27cd95f498f471a1a9fd (patch)
treee236c1a6db6bb4a653a3ebd1cde78e4077095de9
parent6a6534b6e7a2059b3fbe421f1de4cd125f2e5a66 (diff)
downloadv4l2-encode-b3f49cc2e1840a642dbe27cd95f498f471a1a9fd.tar.gz
Enable Request API on Output Buffers
- Allocate request fd for all o/p buffers - Setup control for all buffers - Queue request for each QBUF of o/p buffers - Reinit Request after DQBUF for o/p buffers. Signed-off-by: Dikshita Agarwal <dikshita@codeaurora.org>
-rw-r--r--Makefile2
-rw-r--r--common.h4
-rw-r--r--main.c12
-rw-r--r--video.c132
-rw-r--r--video.h3
5 files changed, 137 insertions, 16 deletions
diff --git a/Makefile b/Makefile
index 8c2bcaf..a263c7c 100644
--- a/Makefile
+++ b/Makefile
@@ -26,7 +26,7 @@ AR = "${TCPATH}ar rc"
AR2 = ${TCPATH}ranlib make -j4
-INCLUDES = -I$(KERNELHEADERS) -I/usr/include/drm
+#INCLUDES = -I$(KERNELHEADERS) -I/usr/include/drm
#INCLUDES = -I$(KERNELHEADERS)/include
diff --git a/common.h b/common.h
index a09ccce..72e8bbc 100644
--- a/common.h
+++ b/common.h
@@ -92,6 +92,8 @@
/* The buffer is free to use by video decoder */
#define BUF_FREE 0
+#define MAX_HDR10PLUSINFO_SIZE 1024
+#define V4L2_CID_MPEG_VIDEO_VENUS_METADATA (V4L2_CID_MPEG_BASE + 293)
/* Input file related parameters */
struct input {
char *name;
@@ -114,6 +116,7 @@ struct output {
struct video {
char *name;
int fd;
+ int media_fd;
/* Output queue related */
unsigned int out_w;
@@ -124,6 +127,7 @@ struct video {
uint32_t out_buf_off[MAX_OUT_BUF];
uint8_t *out_buf_addr[MAX_OUT_BUF];
int out_buf_flag[MAX_OUT_BUF];
+ int request_fd_out[MAX_OUT_BUF];
/* Capture queue related */
unsigned int cap_w;
diff --git a/main.c b/main.c
index 65ce2ba..9d41124 100644
--- a/main.c
+++ b/main.c
@@ -24,6 +24,7 @@
#include <stdio.h>
#include <string.h>
#include <linux/videodev2.h>
+#include <linux/media.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <poll.h>
@@ -275,10 +276,21 @@ static void *input_thread_func(void *args)
fs = 0;
}
+ ret = video_setup_extra_control_out(i,n);
+ if (ret)
+ {
+ err("Unable to video_setup_extra_control_out: %s\n",strerror(errno));
+ return NULL;
+ }
ret = video_queue_buf_out(i, n, fs);
if (ret)
continue;
+ ret = ioctl(vid->request_fd_out[n], MEDIA_REQUEST_IOC_QUEUE, NULL);
+ if (ret < 0) {
+ err("Unable to queue media request: %s\n",strerror(errno));
+ return NULL;
+ }
pthread_mutex_lock(&i->lock);
vid->out_buf_flag[n] = 1;
pthread_mutex_unlock(&i->lock);
diff --git a/video.c b/video.c
index a5e1a95..3284800 100644
--- a/video.c
+++ b/video.c
@@ -21,6 +21,7 @@
*/
#include <linux/videodev2.h>
+#include <linux/media.h>
#include <linux/v4l2-controls.h>
#include <fcntl.h>
#include <string.h>
@@ -38,6 +39,7 @@
static char *dbg_type[2] = {"OUTPUT", "CAPTURE"};
static char *dbg_status[2] = {"ON", "OFF"};
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
/* check is it a decoder video device */
static int is_video_encoder(int fd, const char *name)
@@ -124,34 +126,41 @@ static int is_video_encoder(int fd, const char *name)
int video_open(struct instance *i, const char *name)
{
char video_name[64];
- unsigned idx = 0, v = 0;
- int ret, fd = -1;
+ char media_name[64];
+ unsigned idxM = 0, idxV = 0, v = 0;
+ int ret, fd = -1, media_fd = -1;
- while (v++ < 32) {
- ret = sprintf(video_name, "/dev/video%d", idx);
+ ret = sprintf(media_name, "/dev/media%d", idxM);
if (ret < 0)
return ret;
- idx++;
+ err("open media device: %s", media_name);
- dbg("open video device: %s", video_name);
+ media_fd = open(media_name, O_RDWR, 0);
+ if (media_fd < 0) {
+ err("Failed to open media device: %s", media_name);
+ return -1;
+ }
+
+ ret = sprintf(video_name, "/dev/video%d", idxV);
+ if (ret < 0)
+ return ret;
+
+ err("open video device: %s", video_name);
fd = open(video_name, O_RDWR, 0);
if (fd < 0) {
err("Failed to open video device: %s", video_name);
- continue;
+ return -1;
}
ret = is_video_encoder(fd, video_name);
if (ret < 0) {
close(fd);
- continue;
+ close(media_fd);
+ return -1;
}
- if (!ret)
- break;
- }
-
if (!ret)
info("found encoder video device %s", video_name);
@@ -164,13 +173,15 @@ int video_open(struct instance *i, const char *name)
}
i->video.fd = fd;
+ i->video.media_fd = media_fd;
- return 0;
+ return 0;
}
void video_close(struct instance *i)
{
close(i->video.fd);
+ close(i->video.media_fd);
}
int video_set_control(struct instance *i)
@@ -305,6 +316,71 @@ int video_set_control(struct instance *i)
return 0;
}
+int set_extra_control(int video_fd, int request_fd, unsigned int id,
+ void *data, unsigned int size)
+{
+ struct v4l2_ext_control control;
+ struct v4l2_ext_controls controls;
+ int rc;
+ err("set_extra_control");
+ memset(&control, 0, sizeof(control));
+ memset(&controls, 0, sizeof(controls));
+
+ control.id = id;
+ control.ptr = data;
+ control.size = size;
+
+ controls.controls = &control;
+ controls.count = 1;
+
+ if (request_fd >= 0) {
+ controls.which = V4L2_CTRL_WHICH_REQUEST_VAL;
+ controls.request_fd = request_fd;
+ }
+
+ rc = ioctl(video_fd, VIDIOC_S_EXT_CTRLS, &controls);
+ if (rc < 0) {
+ err("Unable to set control: %d %s\n", errno,strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+int video_setup_extra_control_out(struct instance *inst, unsigned int index)
+{
+ struct video *vid = &inst->video;
+ int rc;
+ unsigned int i;
+ err("video_setup_extra_control_out index %d",index);
+ struct v4l2_ctrl_venus_metadata {
+ unsigned int index;
+ //__u8 hdr10plus[16];
+ } hdr10plusInfo[] = {{1},{2},{3},{4},{5},{6},{7},{8},{9}};
+
+ if (index >= vid->out_buf_cnt) {
+ err("Tried to queue a non exisiting buffer");
+ return -1;
+ }
+ struct {
+ char *description;
+ unsigned int id;
+ void *data;
+ unsigned int size;
+ } controls[] = {{"HDR10", V4L2_CID_MPEG_VIDEO_VENUS_METADATA , &hdr10plusInfo[index+vid->cap_buf_cnt], sizeof(hdr10plusInfo)}};
+ for (i = 0; i < ARRAY_SIZE(controls); i++) {
+ struct v4l2_ctrl_venus_metadata *meta = controls[i].data;
+ err("set_extra_control : vid->fd %d vid->request_fd_out[%d] %d meta index %d",vid->fd,index,vid->request_fd_out[index],meta->index);
+ rc = set_extra_control(vid->fd, vid->request_fd_out[index], controls[i].id, controls[i].data,
+ controls[i].size);
+ if (rc < 0) {
+ err("Unable to set %s control\n", controls[i].description);
+ fprintf(stderr, "Unable to set %s control\n",strerror(errno));
+ return -1;
+ }
+ }
+ return rc;
+}
int video_export_buf(struct instance *i, unsigned int index)
{
struct video *vid = &i->video;
@@ -342,6 +418,7 @@ static int video_queue_buf(struct instance *i, unsigned int index,
struct v4l2_plane planes[2];
struct timeval tv;
int ret;
+ int request_fd = -1;
memzero(buf);
memset(planes, 0, sizeof(planes));
@@ -357,6 +434,14 @@ static int video_queue_buf(struct instance *i, unsigned int index,
buf.m.planes[0].data_offset = 0;
buf.m.planes[1].data_offset = 0;
+ if(type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+ request_fd = vid->request_fd_out[index];
+ if (request_fd >= 0) {
+ err("request_fd %d", request_fd);
+ buf.flags = V4L2_BUF_FLAG_REQUEST_FD;
+ buf.request_fd = request_fd;
+ }
+
if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
buf.m.planes[0].length = vid->cap_buf_size[0];
} else {
@@ -375,9 +460,10 @@ static int video_queue_buf(struct instance *i, unsigned int index,
ret = ioctl(vid->fd, VIDIOC_QBUF, &buf);
if (ret) {
- err("Failed to queue buffer (index=%d) on %s (%s)",
+ err("Failed to queue buffer (index=%d) on %s %u (%s)",
buf.index,
dbg_type[type==V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE],
+ errno,
strerror(errno));
return -1;
}
@@ -440,6 +526,7 @@ int video_dequeue_output(struct instance *i, unsigned int *n)
struct v4l2_buffer buf;
struct v4l2_plane planes[OUT_PLANES];
int ret;
+ int request_fd = -1;
memzero(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
@@ -452,7 +539,13 @@ int video_dequeue_output(struct instance *i, unsigned int *n)
return ret;
*n = buf.index;
-
+ request_fd = i->video.request_fd_out[*n];
+ ret = ioctl(request_fd, MEDIA_REQUEST_IOC_REINIT, NULL);
+ if (ret < 0) {
+ fprintf(stderr, "Unable to reinit media request for fd %d: %s\n",
+ request_fd,strerror(errno));
+ //return -1;
+ }
return 0;
}
@@ -623,6 +716,7 @@ int video_setup_output(struct instance *i, unsigned long codec,
struct v4l2_plane planes[OUT_PLANES];
int ret;
int n;
+ int request_fd = -1;
memzero(try_fmt);
try_fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
@@ -727,6 +821,14 @@ int video_setup_output(struct instance *i, unsigned long codec,
}
vid->out_buf_flag[n] = 0;
+
+ ret = ioctl(vid->media_fd, MEDIA_IOC_REQUEST_ALLOC, &request_fd);
+ if (ret) {
+ err("Unable to allocate media request %u (%s)", errno,strerror(errno));
+ return -1;
+ }
+ vid->request_fd_out[n] = request_fd;
+ err("request_fd %d vid->request_fd_out[%d] %d", request_fd,n,vid->request_fd_out[n]);
}
info("OUTPUT: Succesfully mmapped %u buffers", n);
diff --git a/video.h b/video.h
index 30b31d2..aa44b0f 100644
--- a/video.h
+++ b/video.h
@@ -64,6 +64,9 @@ int video_dequeue_capture(struct instance *i, unsigned int *n,
unsigned int *finished, unsigned int *bytesused,
unsigned int *data_offset, unsigned int *buf_flags);
int video_set_control(struct instance *i);
+int set_extra_control(int video_fd, int request_fd, unsigned int id,
+ void *data, unsigned int size);
+int video_setup_extra_control_out(struct instance *i, unsigned int index);
int video_stop(struct instance *i);