aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--args.c15
-rw-r--r--common.h8
-rw-r--r--gentest.c15
-rw-r--r--gentest.h4
-rw-r--r--main.c29
-rw-r--r--video.c105
-rw-r--r--video.h6
7 files changed, 63 insertions, 119 deletions
diff --git a/args.c b/args.c
index e2248a6..54fa956 100644
--- a/args.c
+++ b/args.c
@@ -35,7 +35,7 @@ void print_usage(char *name)
printf("Usage:\n");
printf("\t%s\n", name);
printf("\t-c <codec> - The codec to be used for encoding\n");
- printf("\t\t Available codecs: mpeg4, h264, h263, xvid, mpeg2, mpeg1, vp8\n");
+ printf("\t\t Available codecs: mpeg4, h264, h265, h263, xvid, mpeg2, mpeg1, vp8, vp9\n");
printf("\t-d use dmabuf instead of mmap\n");
printf("\t-m <device> - video encoder device (e.g. /dev/video33)\n");
printf("\t-w video width\n");
@@ -45,6 +45,7 @@ void print_usage(char *name)
printf("\t-v verbose mode\n");
printf("\t-B bitrate\n");
printf("\t-F framerate\n");
+ printf("\t-b number of B frames\n");
printf("\n");
}
@@ -69,6 +70,10 @@ int get_codec(char *str)
return V4L2_PIX_FMT_MPEG1;
} else if (strncasecmp("vp8", str, 5) == 0) {
return V4L2_PIX_FMT_VP8;
+ } else if (strncasecmp("vp9", str, 5) == 0) {
+ return V4L2_PIX_FMT_VP9;
+ } else if (strncasecmp("h265", str, 5) == 0) {
+ return V4L2_PIX_FMT_HEVC;
}
return 0;
}
@@ -79,7 +84,7 @@ int parse_args(struct instance *i, int argc, char **argv)
init_to_defaults(i);
- while ((c = getopt(argc, argv, "w:h:c:d:m:f:n:gvB:F:")) != -1) {
+ while ((c = getopt(argc, argv, "w:h:c:d:m:f:n:gvB:F:b:")) != -1) {
switch (c) {
case 'c':
i->codec = get_codec(optarg);
@@ -116,6 +121,12 @@ int parse_args(struct instance *i, int argc, char **argv)
case 'F':
i->framerate = atoi(optarg);
break;
+ case 'b':
+ i->num_bframes = atoi(optarg);
+ break;
+ case 'p':
+ i->num_pframes = atoi(optarg);
+ break;
default:
err("Bad argument");
return -1;
diff --git a/common.h b/common.h
index cd2c0d8..7516a3b 100644
--- a/common.h
+++ b/common.h
@@ -63,6 +63,9 @@
#define dbg(...) {}
#endif /* DEBUG */
+#define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C') /* HEVC */
+#define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0') /* VP9 */
+
#define memzero(x) memset(&(x), 0, sizeof (x));
#define ALIGN(val, align) ((val + (align - 1)) & ~(align - 1))
@@ -113,6 +116,9 @@ struct video {
int fd;
/* Output queue related */
+ unsigned int out_w;
+ unsigned int out_h;
+ unsigned int out_bytesperline;
unsigned int out_buf_cnt;
unsigned int out_buf_size;
uint32_t out_buf_off[MAX_OUT_BUF];
@@ -158,6 +164,8 @@ struct instance {
unsigned int bitrate;
unsigned int framerate;
+ unsigned int num_bframes;
+ unsigned int num_pframes;
/* Codec to be used for encoding */
unsigned long codec;
diff --git a/gentest.c b/gentest.c
index 03d9340..0bdf3a1 100644
--- a/gentest.c
+++ b/gentest.c
@@ -139,10 +139,17 @@ static void fill_yuv_planar(unsigned char *y_mem, unsigned char *u_mem,
static void *testbuf;
-int gentest_init(unsigned int width, unsigned int height, unsigned int size)
+int gentest_init(unsigned int width, unsigned int height, unsigned int stride,
+ unsigned int crop_w, unsigned int crop_h,
+ unsigned int size)
{
- unsigned int stride = ALIGN(width, 128);
unsigned char *y_mem, *u_mem, *v_mem;
+ unsigned int w = width, h = height;
+
+ if (crop_w && crop_h) {
+ w = crop_w;
+ h = crop_h;
+ }
srand(1);
@@ -151,10 +158,10 @@ int gentest_init(unsigned int width, unsigned int height, unsigned int size)
return -1;
y_mem = testbuf;
- u_mem = testbuf + stride * ALIGN(height, 32);
+ u_mem = testbuf + stride * height;
v_mem = u_mem + 1;
- fill_yuv_planar(y_mem, u_mem, v_mem, width, height, stride);
+ fill_yuv_planar(y_mem, u_mem, v_mem, w, h, stride);
return 0;
}
diff --git a/gentest.h b/gentest.h
index 64d8fb7..1c10d84 100644
--- a/gentest.h
+++ b/gentest.h
@@ -1,7 +1,9 @@
#ifndef INCLUDE_GENTEST_H
#define INCLUDE_GENTEST_H
-int gentest_init(unsigned int width, unsigned int height, unsigned int size);
+int gentest_init(unsigned int width, unsigned int height, unsigned int stride,
+ unsigned int crop_w, unsigned int crop_h,
+ unsigned int size);
void gentest_deinit(void);
void gentest_fill(unsigned int width, unsigned int height, unsigned char *to,
unsigned int size);
diff --git a/main.c b/main.c
index b945ee9..03af7da 100644
--- a/main.c
+++ b/main.c
@@ -103,7 +103,7 @@ static int handle_v4l_events(struct video *vid)
return 0;
}
-void cleanup(struct instance *i)
+static void cleanup(struct instance *i)
{
if (i->video.fd)
video_close(i);
@@ -113,7 +113,7 @@ void cleanup(struct instance *i)
close(i->out.fd);
}
-int save_encoded(struct instance *i, const void *buf, unsigned int size)
+static int save_encoded(struct instance *i, const void *buf, unsigned int size)
{
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
char filename[64];
@@ -175,7 +175,7 @@ static int input_read(struct instance *inst, unsigned int index,
/* This threads is responsible for reading input file or stream and
* feeding video enccoder with consecutive frames to encode */
-void *input_thread_func(void *args)
+static void *input_thread_func(void *args)
{
struct instance *i = (struct instance *)args;
struct video *vid = &i->video;
@@ -219,7 +219,7 @@ void *input_thread_func(void *args)
return NULL;
}
-void *main_thread_func(void *args)
+static void *main_thread_func(void *args)
{
struct instance *i = (struct instance *)args;
struct video *vid = &i->video;
@@ -256,12 +256,7 @@ void *main_thread_func(void *args)
dbg("dequeuing capture buffer");
- if (i->use_dmabuf)
- ret = video_dequeue_capture_dmabuf(
- i, &n, &finished, &bytesused);
- else
- ret = video_dequeue_capture(i, &n, &finished,
- &bytesused);
+ ret = video_dequeue_capture(i, &n, &finished, &bytesused);
if (ret < 0)
goto next_event;
@@ -343,11 +338,7 @@ int main(int argc, char **argv)
if (ret)
goto err;
- if (inst.use_dmabuf)
- ret = video_setup_capture_dmabuf(&inst, 2, inst.width,
- inst.height);
- else
- ret = video_setup_capture(&inst, 2, inst.width, inst.height);
+ ret = video_setup_capture(&inst, 2, inst.width, inst.height);
if (ret)
goto err;
@@ -355,7 +346,13 @@ int main(int argc, char **argv)
if (ret)
goto err;
- ret = gentest_init(inst.width, inst.height, vid->out_buf_size);
+ info("gentest init: %ux%u, bpl:%u, crop_w:%u, crop_h:%u",
+ vid->out_w, vid->out_h, vid->out_bytesperline,
+ inst.width, inst.height);
+
+ ret = gentest_init(vid->out_w, vid->out_h, vid->out_bytesperline,
+ inst.width, inst.height,
+ vid->out_buf_size);
if (ret)
goto err;
diff --git a/video.c b/video.c
index e5a08c0..ae07eda 100644
--- a/video.c
+++ b/video.c
@@ -34,7 +34,6 @@
#include "common.h"
-/* mem2mem encoder/decoder */
#define V4L2_BUF_FLAG_LAST 0x00100000
static char *dbg_type[2] = {"OUTPUT", "CAPTURE"};
@@ -183,13 +182,17 @@ int video_set_control(struct instance *i)
if (ret)
err("set control - level (%s)", strerror(errno));
- memset(&cntrl, 0, sizeof(cntrl));
- cntrl.id = V4L2_CID_MPEG_VIDEO_B_FRAMES;
- cntrl.value = 1;
- info("setting num b frames: %u", cntrl.value);
- ret = ioctl(i->video.fd, VIDIOC_S_CTRL, &cntrl);
- if (ret)
- err("set control - num b frames (%s)", strerror(errno));
+ if (i->num_bframes && i->num_bframes < 4) {
+ memset(&cntrl, 0, sizeof(cntrl));
+ cntrl.id = V4L2_CID_MPEG_VIDEO_B_FRAMES;
+// cntrl.value = 1;
+ cntrl.value = i->num_bframes;
+ info("setting num b frames: %u", cntrl.value);
+ ret = ioctl(i->video.fd, VIDIOC_S_CTRL, &cntrl);
+ if (ret)
+ err("set control - num b frames (%s)",
+ strerror(errno));
+ }
}
#if 0
@@ -416,33 +419,6 @@ int video_dequeue_capture(struct instance *i, unsigned int *n,
return 0;
}
-int video_dequeue_capture_dmabuf(struct instance *i, unsigned int *n,
- unsigned int *finished,
- unsigned int *bytesused)
-{
- struct v4l2_buffer buf;
- struct v4l2_plane planes[CAP_PLANES];
-
- memzero(buf);
- buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- buf.memory = V4L2_MEMORY_DMABUF;
- buf.m.planes = planes;
- buf.length = CAP_PLANES;
-
- if (video_dequeue_buf(i, &buf))
- return -1;
-
- *finished = 0;
-
- if (buf.flags & V4L2_BUF_FLAG_LAST || buf.m.planes[0].bytesused == 0)
- *finished = 1;
-
- *bytesused = buf.m.planes[0].bytesused;
- *n = buf.index;
-
- return 0;
-}
-
int video_stream(struct instance *i, enum v4l2_buf_type type,
unsigned int status)
{
@@ -569,61 +545,6 @@ int video_setup_capture(struct instance *i, unsigned int count, unsigned int w,
return 0;
}
-int video_setup_capture_dmabuf(struct instance *i, unsigned int count,
- unsigned int w, unsigned int h)
-{
- struct video *vid = &i->video;
- struct v4l2_format fmt;
- struct v4l2_requestbuffers reqbuf;
- int ret;
-
- memzero(fmt);
- fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- fmt.fmt.pix_mp.height = h;
- fmt.fmt.pix_mp.width = w;
- fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
- ret = ioctl(vid->fd, VIDIOC_S_FMT, &fmt);
- if (ret) {
- err("CAPTURE: S_FMT failed (%ux%u) (%s)", w, h, strerror(errno));
- return -1;
- }
-
- info("CAPTURE: Set format %ux%u, sizeimage %u, bpl %u",
- fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
- fmt.fmt.pix_mp.plane_fmt[0].sizeimage,
- fmt.fmt.pix_mp.plane_fmt[0].bytesperline);
-
- vid->cap_w = fmt.fmt.pix_mp.width;
- vid->cap_h = fmt.fmt.pix_mp.height;
-
- vid->cap_buf_size[0] = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
- vid->cap_buf_size[1] = fmt.fmt.pix_mp.plane_fmt[1].sizeimage;
-
- vid->cap_buf_cnt_min = 1;
- vid->cap_buf_queued = 0;
-
- memzero(reqbuf);
- reqbuf.count = count;
- reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- reqbuf.memory = V4L2_MEMORY_DMABUF;
-
- ret = ioctl(vid->fd, VIDIOC_REQBUFS, &reqbuf);
- if (ret) {
- err("CAPTURE: REQBUFS failed (%s)", strerror(errno));
- return -1;
- }
-
- vid->cap_buf_cnt = reqbuf.count;
-
- info("CAPTURE: Number of buffers %u (requested %u)",
- vid->cap_buf_cnt, count);
-
- info("CAPTURE: Succesfully requested %u dmabuf buffers",
- vid->cap_buf_cnt);
-
- return 0;
-}
-
int video_setup_output(struct instance *i, unsigned long codec,
unsigned int size, unsigned int count)
{
@@ -689,6 +610,10 @@ int video_setup_output(struct instance *i, unsigned long codec,
g_fmt.fmt.pix_mp.plane_fmt[0].sizeimage,
g_fmt.fmt.pix_mp.plane_fmt[0].bytesperline);
+ vid->out_w = g_fmt.fmt.pix_mp.width;
+ vid->out_h = g_fmt.fmt.pix_mp.height;
+ vid->out_bytesperline = g_fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
+
memzero(reqbuf);
reqbuf.count = count;
reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
diff --git a/video.h b/video.h
index efca81b..b1572c8 100644
--- a/video.h
+++ b/video.h
@@ -43,8 +43,6 @@ int video_setup_output(struct instance *i, unsigned long codec,
* structure. */
int video_setup_capture(struct instance *i, unsigned int count, unsigned int w,
unsigned int h);
-int video_setup_capture_dmabuf(struct instance *i, unsigned int count,
- unsigned int w, unsigned int h);
/* Queue OUTPUT buffer */
int video_queue_buf_out(struct instance *i, unsigned int n,
@@ -65,10 +63,6 @@ int video_dequeue_output(struct instance *i, unsigned int *n);
int video_dequeue_capture(struct instance *i, unsigned int *n,
unsigned int *finished,
unsigned int *bytesused);
-int video_dequeue_capture_dmabuf(struct instance *i, unsigned int *n,
- unsigned int *finished,
- unsigned int *bytesused);
-
int video_set_control(struct instance *i);
int video_stop(struct instance *i);