2 * Copyright (C) 2007 Benjamin Zores
3 * Video output for V4L2 hardware MPEG decoders.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 #include <sys/types.h>
28 #include <sys/ioctl.h>
33 #include <linux/types.h>
34 #include <linux/videodev2.h>
35 #include <linux/ioctl.h>
38 #include "subopt-helper.h"
39 #include "video_out.h"
40 #include "video_out_internal.h"
41 #include "libmpdemux/mpeg_packetizer.h"
43 #define DEFAULT_MPEG_DECODER "/dev/video16"
44 #define V4L2_VO_HDR "VO: [v4l2]"
47 static vo_mpegpes_t
*pes
;
50 static int output
= -1;
51 static char *device
= NULL
;
53 static opt_t subopts
[] = {
54 {"output", OPT_ARG_INT
, &output
, (opt_test_f
)int_non_neg
},
55 {"device", OPT_ARG_MSTRZ
, &device
, NULL
},
59 static const vo_info_t info
=
61 "V4L2 MPEG Video Decoder Output",
66 const LIBVO_EXTERN (v4l2
)
69 v4l2_write (unsigned char *data
, int len
)
74 return write (v4l2_fd
, data
, len
);
77 /* video out functions */
80 config (uint32_t width
, uint32_t height
,
81 uint32_t d_width
, uint32_t d_height
,
82 uint32_t fullscreen
, char *title
, uint32_t format
)
88 preinit (const char *arg
)
90 struct v4l2_output vout
;
91 struct v4l2_ext_controls ctrls
;
94 if (subopt_parse (arg
, subopts
) != 0)
96 mp_msg (MSGT_VO
, MSGL_FATAL
,
97 "\n-vo v4l2 command line help:\n"
98 "Example: mplayer -vo v4l2:device=/dev/video16:output=2\n"
100 " device=/dev/videoX\n"
101 " Name of the MPEG decoder device file.\n"
103 " V4L2 id of the TV output.\n"
109 device
= strdup (DEFAULT_MPEG_DECODER
);
111 v4l2_fd
= open (device
, O_RDWR
);
115 mp_msg (MSGT_VO
, MSGL_FATAL
, "%s %s\n", V4L2_VO_HDR
, strerror (errno
));
119 /* check for device hardware MPEG decoding capability */
120 ctrls
.ctrl_class
= V4L2_CTRL_CLASS_MPEG
;
122 ctrls
.controls
= NULL
;
124 if (ioctl (v4l2_fd
, VIDIOC_G_EXT_CTRLS
, &ctrls
) < 0)
127 mp_msg (MSGT_OPEN
, MSGL_FATAL
, "%s %s\n", V4L2_VO_HDR
, strerror (errno
));
131 /* list available outputs */
134 mp_msg (MSGT_VO
, MSGL_INFO
, "%s Available video outputs: ", V4L2_VO_HDR
);
135 while (ioctl (v4l2_fd
, VIDIOC_ENUMOUTPUT
, &vout
) >= 0)
138 mp_msg (MSGT_VO
, MSGL_INFO
, "'#%d, %s' ", vout
.index
, vout
.name
);
143 mp_msg (MSGT_VO
, MSGL_INFO
, "none\n");
148 mp_msg (MSGT_VO
, MSGL_INFO
, "\n");
150 /* set user specified output */
153 if (ioctl (v4l2_fd
, VIDIOC_S_OUTPUT
, &output
) < 0)
155 mp_msg (MSGT_VO
, MSGL_ERR
,
156 "%s can't set output (%s)\n", V4L2_VO_HDR
, strerror (errno
));
162 /* display device name */
163 mp_msg (MSGT_VO
, MSGL_INFO
, "%s using %s\n", V4L2_VO_HDR
, device
);
166 /* display current video output */
167 if (ioctl (v4l2_fd
, VIDIOC_G_OUTPUT
, &output
) == 0)
170 if (ioctl (v4l2_fd
, VIDIOC_ENUMOUTPUT
, &vout
) < 0)
172 mp_msg (MSGT_VO
, MSGL_ERR
,
173 "%s can't get output (%s).\n", V4L2_VO_HDR
, strerror (errno
));
177 mp_msg (MSGT_VO
, MSGL_INFO
,
178 "%s video output: %s\n", V4L2_VO_HDR
, vout
.name
);
182 mp_msg (MSGT_VO
, MSGL_ERR
,
183 "%s can't get output (%s).\n", V4L2_VO_HDR
, strerror (errno
));
197 draw_frame (uint8_t * src
[])
199 pes
= (vo_mpegpes_t
*) src
[0];
212 send_mpeg_pes_packet (pes
->data
, pes
->size
, pes
->id
,
213 pes
->timestamp
? pes
->timestamp
: vo_pts
, 2,
216 /* ensure flip_page() won't be called twice */
221 draw_slice (uint8_t *image
[], int stride
[], int w
, int h
, int x
, int y
)
244 query_format (uint32_t format
)
246 if (format
!= IMGFMT_MPEGPES
)
249 return VFCAP_CSP_SUPPORTED
| VFCAP_CSP_SUPPORTED_BY_HW
| VFCAP_TIMER
;
253 control (uint32_t request
, void *data
, ...)
257 case VOCTRL_QUERY_FORMAT
:
258 return query_format (*((uint32_t*) data
));