From 229380d9bd1995583c38d2cc061d5264e3afb020 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 7 Aug 2012 00:05:40 +0200 Subject: vo_v4l2: reformat, use new VO API Actually, this is probably completely broken, and there are better ways to get mplayer output into a V4L2 device. --- libvo/vo_v4l2.c | 318 +++++++++++++++++++++++++++----------------------------- 1 file changed, 153 insertions(+), 165 deletions(-) (limited to 'libvo') diff --git a/libvo/vo_v4l2.c b/libvo/vo_v4l2.c index d1ee15ca3b..2f5d0f138a 100644 --- a/libvo/vo_v4l2.c +++ b/libvo/vo_v4l2.c @@ -40,7 +40,8 @@ #include "mp_msg.h" #include "subopt-helper.h" #include "video_out.h" -#include "video_out_internal.h" +#include "libmpcodecs/vfcap.h" +#include "libmpcodecs/mp_image.h" #include "libmpdemux/mpeg_packetizer.h" #include "vo_v4l2.h" @@ -55,212 +56,199 @@ static int output = -1; static char *device = NULL; static const opt_t subopts[] = { - {"output", OPT_ARG_INT, &output, int_non_neg}, - {"device", OPT_ARG_MSTRZ, &device, NULL}, - {NULL} + {"output", OPT_ARG_INT, &output, int_non_neg}, + {"device", OPT_ARG_MSTRZ, &device, NULL}, + {NULL} }; -static const vo_info_t info = +int v4l2_write(const unsigned char *data, int len) { - "V4L2 MPEG Video Decoder Output", - "v4l2", - "Benjamin Zores", - "" -}; -const LIBVO_EXTERN (v4l2) - -int -v4l2_write (const unsigned char *data, int len) -{ - if (v4l2_fd < 0) - return 0; + if (v4l2_fd < 0) + return 0; - return write (v4l2_fd, data, len); + return write(v4l2_fd, data, len); } /* video out functions */ -static int -config (uint32_t width, uint32_t height, - uint32_t d_width, uint32_t d_height, - uint32_t fullscreen, char *title, uint32_t format) +static int config(struct vo *vo, uint32_t width, uint32_t height, + uint32_t d_width, uint32_t d_height, + uint32_t fullscreen, uint32_t format) { - return 0; + return 0; } -static int -preinit (const char *arg) +static int preinit(struct vo *vo, const char *arg) { - struct v4l2_output vout; - struct v4l2_ext_controls ctrls; - int err; - - if (subopt_parse (arg, subopts) != 0) - { - mp_msg (MSGT_VO, MSGL_FATAL, - "\n-vo v4l2 command line help:\n" - "Example: mplayer -vo v4l2:device=/dev/video16:output=2\n" - "\nOptions:\n" - " device=/dev/videoX\n" - " Name of the MPEG decoder device file.\n" - " output=<0-...>\n" - " V4L2 id of the TV output.\n" - "\n" ); - return -1; - } - - if (!device) - device = strdup (DEFAULT_MPEG_DECODER); - - v4l2_fd = open (device, O_RDWR); - if (v4l2_fd < 0) - { - free (device); - mp_msg (MSGT_VO, MSGL_FATAL, "%s %s\n", V4L2_VO_HDR, strerror (errno)); - return -1; - } - - /* check for device hardware MPEG decoding capability */ - ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG; - ctrls.count = 0; - ctrls.controls = NULL; - - if (ioctl (v4l2_fd, VIDIOC_G_EXT_CTRLS, &ctrls) < 0) - { - free (device); - mp_msg (MSGT_OPEN, MSGL_FATAL, "%s %s\n", V4L2_VO_HDR, strerror (errno)); - return -1; - } - - /* list available outputs */ - vout.index = 0; - err = 1; - mp_msg (MSGT_VO, MSGL_INFO, "%s Available video outputs: ", V4L2_VO_HDR); - while (ioctl (v4l2_fd, VIDIOC_ENUMOUTPUT, &vout) >= 0) - { - err = 0; - mp_msg (MSGT_VO, MSGL_INFO, "'#%d, %s' ", vout.index, vout.name); - vout.index++; - } - if (err) - { - mp_msg (MSGT_VO, MSGL_INFO, "none\n"); - free (device); - return -1; - } - else - mp_msg (MSGT_VO, MSGL_INFO, "\n"); - - /* set user specified output */ - if (output != -1) - { - if (ioctl (v4l2_fd, VIDIOC_S_OUTPUT, &output) < 0) - { - mp_msg (MSGT_VO, MSGL_ERR, - "%s can't set output (%s)\n", V4L2_VO_HDR, strerror (errno)); - free (device); - return -1; + struct v4l2_output vout; + struct v4l2_ext_controls ctrls; + int err; + + if (subopt_parse(arg, subopts) != 0) { + mp_msg(MSGT_VO, MSGL_FATAL, + "\n-vo v4l2 command line help:\n" + "Example: mplayer -vo v4l2:device=/dev/video16:output=2\n" + "\nOptions:\n" + " device=/dev/videoX\n" + " Name of the MPEG decoder device file.\n" + " output=<0-...>\n" + " V4L2 id of the TV output.\n" + "\n"); + return -1; + } + + if (!device) + device = strdup(DEFAULT_MPEG_DECODER); + + v4l2_fd = open(device, O_RDWR); + if (v4l2_fd < 0) { + free(device); + mp_msg(MSGT_VO, MSGL_FATAL, "%s %s\n", V4L2_VO_HDR, strerror(errno)); + return -1; + } + + /* check for device hardware MPEG decoding capability */ + ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG; + ctrls.count = 0; + ctrls.controls = NULL; + + if (ioctl(v4l2_fd, VIDIOC_G_EXT_CTRLS, &ctrls) < 0) { + free(device); + mp_msg(MSGT_OPEN, MSGL_FATAL, "%s %s\n", V4L2_VO_HDR, strerror(errno)); + return -1; } - } - - /* display device name */ - mp_msg (MSGT_VO, MSGL_INFO, "%s using %s\n", V4L2_VO_HDR, device); - free (device); - - /* display current video output */ - if (ioctl (v4l2_fd, VIDIOC_G_OUTPUT, &output) == 0) - { - vout.index = output; - if (ioctl (v4l2_fd, VIDIOC_ENUMOUTPUT, &vout) < 0) - { - mp_msg (MSGT_VO, MSGL_ERR, - "%s can't get output (%s).\n", V4L2_VO_HDR, strerror (errno)); - return -1; + + /* list available outputs */ + vout.index = 0; + err = 1; + mp_msg(MSGT_VO, MSGL_INFO, "%s Available video outputs: ", V4L2_VO_HDR); + while (ioctl(v4l2_fd, VIDIOC_ENUMOUTPUT, &vout) >= 0) { + err = 0; + mp_msg(MSGT_VO, MSGL_INFO, "'#%d, %s' ", vout.index, vout.name); + vout.index++; } - else - mp_msg (MSGT_VO, MSGL_INFO, - "%s video output: %s\n", V4L2_VO_HDR, vout.name); - } - else - { - mp_msg (MSGT_VO, MSGL_ERR, - "%s can't get output (%s).\n", V4L2_VO_HDR, strerror (errno)); - return -1; - } - - return 0; + if (err) { + mp_msg(MSGT_VO, MSGL_INFO, "none\n"); + free(device); + return -1; + } else + mp_msg(MSGT_VO, MSGL_INFO, "\n"); + + /* set user specified output */ + if (output != -1) { + if (ioctl(v4l2_fd, VIDIOC_S_OUTPUT, &output) < 0) { + mp_msg(MSGT_VO, MSGL_ERR, + "%s can't set output (%s)\n", V4L2_VO_HDR, strerror(errno)); + free(device); + return -1; + } + } + + /* display device name */ + mp_msg(MSGT_VO, MSGL_INFO, "%s using %s\n", V4L2_VO_HDR, device); + free(device); + + /* display current video output */ + if (ioctl(v4l2_fd, VIDIOC_G_OUTPUT, &output) == 0) { + vout.index = output; + if (ioctl(v4l2_fd, VIDIOC_ENUMOUTPUT, &vout) < 0) { + mp_msg(MSGT_VO, MSGL_ERR, + "%s can't get output (%s).\n", V4L2_VO_HDR, strerror(errno)); + return -1; + } else + mp_msg(MSGT_VO, MSGL_INFO, + "%s video output: %s\n", V4L2_VO_HDR, vout.name); + } else { + mp_msg(MSGT_VO, MSGL_ERR, + "%s can't get output (%s).\n", V4L2_VO_HDR, strerror(errno)); + return -1; + } + + return 0; } -static void -draw_osd (void) +static void draw_osd(struct vo *vo, struct osd_state *osd) { - /* do nothing */ + /* do nothing */ } -static int -draw_frame (uint8_t * src[]) +static uint32_t draw_image(struct vo *vo, mp_image_t *mpi) { - pes = (vo_mpegpes_t *) src[0]; - return 0; + pes = (vo_mpegpes_t *) (mpi->planes[0]); + return 0; } -static void -flip_page (void) +static void flip_page(struct vo *vo) { - if (v4l2_fd < 0) - return; + if (v4l2_fd < 0) + return; - if (!pes) - return; + if (!pes) + return; - send_mpeg_pes_packet (pes->data, pes->size, pes->id, - pes->timestamp ? pes->timestamp : vo_pts, 2, - v4l2_write); + send_mpeg_pes_packet(pes->data, pes->size, pes->id, + pes->timestamp ? pes->timestamp : vo_pts, 2, + v4l2_write); - /* ensure flip_page() won't be called twice */ - pes = NULL; + /* ensure flip_page() won't be called twice */ + pes = NULL; } -static int -draw_slice (uint8_t *image[], int stride[], int w, int h, int x, int y) +static int draw_slice(struct vo *vo, uint8_t *image[], int stride[], + int w, int h, int x, int y) { - return 0; + return 0; } -static void -uninit (void) +static void uninit(struct vo *vo) { - if (v4l2_fd < 0) - return; + if (v4l2_fd < 0) + return; - /* close device */ - close (v4l2_fd); - v4l2_fd = -1; + /* close device */ + close(v4l2_fd); + v4l2_fd = -1; } -static void -check_events (void) +static void check_events(struct vo *vo) { - /* do nothing */ + /* do nothing */ } -static int -query_format (uint32_t format) +static int query_format(struct vo *vo, uint32_t format) { - if (format != IMGFMT_MPEGPES) - return 0; + if (format != IMGFMT_MPEGPES) + return 0; - return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_TIMER; + return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_TIMER; } -static int -control (uint32_t request, void *data) +static int control(struct vo *vo, uint32_t request, void *data) { - switch (request) - { - case VOCTRL_QUERY_FORMAT: - return query_format (*((uint32_t*) data)); - } + switch (request) { + case VOCTRL_QUERY_FORMAT: + return query_format(vo, *((uint32_t *) data)); + case VOCTRL_DRAW_IMAGE: + return draw_image(vo, data); + } - return VO_NOTIMPL; + return VO_NOTIMPL; } + +const struct vo_driver video_out_v4l2 = { + .is_new = false, + .info = &(const vo_info_t) { + "V4L2 MPEG Video Decoder Output", + "v4l2", + "Benjamin Zores", + "" + }, + .preinit = preinit, + .config = config, + .control = control, + .draw_slice = draw_slice, + .draw_osd = draw_osd, + .flip_page = flip_page, + .check_events = check_events, + .uninit = uninit, +}; -- cgit v1.2.3