diff options
author | Stanimir Varbanov <stanimir.varbanov@linaro.org> | 2017-07-28 17:16:48 +0300 |
---|---|---|
committer | Stanimir Varbanov <stanimir.varbanov@linaro.org> | 2017-07-28 17:16:48 +0300 |
commit | 4192cc1d60335a45cac7eff67f1c4713106b2bb3 (patch) | |
tree | 38dc4b3028598fb40a8f94a576f7bd697e8a0485 | |
parent | 9b784867fa0dd2df261876e1035aad13ce087b3f (diff) | |
download | v4l2-encode-4192cc1d60335a45cac7eff67f1c4713106b2bb3.tar.gz |
various cleanups and additions
Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
-rw-r--r-- | args.c | 15 | ||||
-rw-r--r-- | common.h | 8 | ||||
-rw-r--r-- | gentest.c | 15 | ||||
-rw-r--r-- | gentest.h | 4 | ||||
-rw-r--r-- | main.c | 29 | ||||
-rw-r--r-- | video.c | 105 | ||||
-rw-r--r-- | video.h | 6 |
7 files changed, 63 insertions, 119 deletions
@@ -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; @@ -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; @@ -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; } @@ -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); @@ -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; @@ -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; @@ -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); |