Pvrinput-plugin
(→Hardwareanforderungen) |
(→Softwareanforderungen) |
||
Zeile 20: | Zeile 20: | ||
==Softwareanforderungen== | ==Softwareanforderungen== | ||
− | * ivtv Treiber | + | * ivtv Treiber |
+ | Die letzte reguläre pvrinput-Version 0.1.1 läuft nur mit ivtv-Treiberversionen bis 0.7. Ab ivtv-Treiber 0.8 ist pvrinput-1.0.0_20070523 erforderlich. Empfohlen wird ivtv-Treiber 1.x.x. Seit August 2007 erfordert der ivtv-Treiber 1.x.x im v4l-dvb hg einen Encoder-Stop/Neustart, wenn der Input gewechselt oder auf den radio tuner umgeschaltet wird. Diese Änderung ist auch in Kernel 2.6.24 eingeflossen. In pvrinput-1.0.0_20070523 muss hierzu der "Anti-Flacker workaround" im plugin-setup aktiviert werden. | ||
<!-- ==Bedienung== --> | <!-- ==Bedienung== --> | ||
Zeile 32: | Zeile 33: | ||
<!-- ===Einstellungen=== --> | <!-- ===Einstellungen=== --> | ||
<!-- ===Parameter=== --> | <!-- ===Parameter=== --> | ||
+ | |||
==Sonstiges== | ==Sonstiges== | ||
===Probleme=== | ===Probleme=== |
Version vom 3. Februar 2008, 14:47 Uhr
Inhaltsverzeichnis |
Beschreibung
Autor: Andreas Regel (bis 2006). Weiterentwicklung seitdem durch Winfried Koehler und Martin Dauskardt
Dieses Plugin ermöglicht es, analoges TV (und UKW-Radio) mit dem VDR in Verbindung mit einer vom Plugin unterstützen PVR-Karte zu benutzen. Die Funktion ist prinzipiell die gleiche wie beim analogtv-plugin, die Bedienung und Einrichtung jedoch deutlich einfacher. Mit ivtv >= 0.8.0 wurde die Treiber Struktur geändert, so dass die letzte reguläre Version 0.1.1 von pvrinput damit nicht mehr funktioniert. Für die Erstellung der channels.conf siehe das README zum Plugin. Alternativ kann die channels.conf auch mit w pvrscan oder dem Wirbelscan-plugin erstellt werden, die einen automatischen Kanalsuchlauf durchführen.
Hardwareanforderungen
Unterstützt werden derzeit die folgenden PCI-Karten: PVR150, PVR250, PVR350 (Encoder-Teil), PVR500. Für die PVRUSB2 muss das pvrusb2-plugin verwandt werden.
Softwareanforderungen
- ivtv Treiber
Die letzte reguläre pvrinput-Version 0.1.1 läuft nur mit ivtv-Treiberversionen bis 0.7. Ab ivtv-Treiber 0.8 ist pvrinput-1.0.0_20070523 erforderlich. Empfohlen wird ivtv-Treiber 1.x.x. Seit August 2007 erfordert der ivtv-Treiber 1.x.x im v4l-dvb hg einen Encoder-Stop/Neustart, wenn der Input gewechselt oder auf den radio tuner umgeschaltet wird. Diese Änderung ist auch in Kernel 2.6.24 eingeflossen. In pvrinput-1.0.0_20070523 muss hierzu der "Anti-Flacker workaround" im plugin-setup aktiviert werden.
Sonstiges
Probleme
Teletext-Problem
- Mit neueren Versionen der IVTV-Treiber kann es beim Setzen des VBI-Modes zu Fehlern kommen. Im Zusammenhang mit dem osdteletext-Plugins kann daher für analoges TV kein Teletext angezeigt werden.
Die Fehlermeldungen lauten:
- IVTV_IOC_G_CODEC failed, 22: Das Argument ist ungültig.
- Error setting vbi embedded mode, 22: Das Argument ist ungültig.
Die Lösung ist die Datei device.c zu patchen:
--- device.c.old 2006-04-30 17:35:56.000000000 +0200 +++ device.c 2007-04-04 22:51:32.000000000 +0200 @@ -408,18 +408,36 @@ if (vbi_fd > 0) { - int vbi_insert = 1; - if (ioctl(vbi_fd, IVTV_IOC_S_VBI_EMBED, &vbi_insert) < 0) - { - log(0, "Error setting vbi embedded mode, %d:%s", errno, strerror(errno)); - } - struct v4l2_format vbi_fmt; - vbi_fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; - vbi_fmt.fmt.sliced.service_set = V4L2_SLICED_TELETEXT_B; - if (ioctl(vbi_fd, VIDIOC_S_FMT, &vbi_fmt) < 0) - { - log(0, "Error setting vbi mode, %d:%s", errno, strerror(errno)); - } + struct v4l2_ext_control vbi_ctrl; + vbi_ctrl.id = V4L2_CID_MPEG_STREAM_VBI_FMT; + vbi_ctrl.value = V4L2_MPEG_STREAM_VBI_FMT_IVTV; + + struct v4l2_ext_controls ctrls; + bzero(&ctrls, sizeof(struct v4l2_ext_controls)); + ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG; + ctrls.count = 1; + ctrls.controls = &vbi_ctrl; + + if (ioctl(vbi_fd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0) + { + log(0, "Can't enable VBI recording %d:%s", errno, strerror(errno)); + } + + struct v4l2_format vbifmt; + bzero(&vbifmt, sizeof(struct v4l2_format)); + vbifmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; + vbifmt.fmt.sliced.service_set = V4L2_SLICED_VBI_625; + + if (ioctl(vbi_fd, VIDIOC_S_FMT, &vbifmt) < 0) + { + log(0, "Can't enable VBI recording %d:%s", errno, strerror(errno)); + + } + + if (ioctl(vbi_fd, VIDIOC_G_FMT, &vbifmt) >= 0) + { + log(0, "VBI service: %d, io size: %d" ,vbifmt.fmt.sliced.service_set, vbifmt.fmt.sliced.io_size); + } } while (active) @@ -734,38 +752,65 @@ bool cPvrDevice::SetCodec(void) { - struct ivtv_ioctl_codec codec; + static const uint numCtrls = 7; + struct v4l2_ext_controls ctrls; + struct v4l2_ext_control ext_ctrl[numCtrls]; - if (IOCTL(video_fd, IVTV_IOC_G_CODEC, &codec) != 0) - { - log(0, "IVTV_IOC_G_CODEC failed, %d:%s", errno, strerror(errno)); - return false; - } - codec.stream_type = IVTV_STREAM_PS; // IVTV_STREAM_DVD_S2 - codec.aspect = PvrSetup.AspectRatio + 1; - codec.pulldown = PvrSetup.Pulldown; - codec.bitrate = PvrSetup.VideoBitrate * 1000; - codec.bitrate_peak = 15000000; - codec.bitrate_mode = bitrateCBR; + /* Set controls */ + bzero(&ctrls, sizeof(struct v4l2_ext_controls)); + bzero(&ext_ctrl, sizeof(struct v4l2_ext_control) * numCtrls); - codec.framespergop = PvrSetup.FramesPerGop; // 15 for NTSC - codec.bframes = PvrSetup.BFrames + 1; - codec.gop_closure = PvrSetup.GopClosure; + ext_ctrl[0].id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ; + ext_ctrl[0].value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000; - codec.dnr_mode = PvrSetup.DnrMode; - codec.dnr_type = PvrSetup.DnrType; - codec.dnr_spatial = PvrSetup.DnrSpatial; - codec.dnr_temporal = PvrSetup.DnrTemporal; + ext_ctrl[2].id = V4L2_CID_MPEG_AUDIO_ENCODING; + ext_ctrl[2].value = V4L2_MPEG_AUDIO_ENCODING_LAYER_2; - codec.audio_bitmask = 0x0009 | ((PvrSetup.AudioBitrate + 1) << 4); - codec.framerate = 1; + ext_ctrl[3].id = V4L2_CID_MPEG_AUDIO_L2_BITRATE; + ext_ctrl[3].value = PvrSetup.AudioBitrate; - if (IOCTL(video_fd, IVTV_IOC_S_CODEC, &codec) != 0) - { - log(0, "IVTV_IOC_S_CODEC failed, %d:%s", errno, strerror(errno)); - return false; - } - return true; + + ext_ctrl[1].id = V4L2_CID_MPEG_VIDEO_ASPECT; + ext_ctrl[1].value = PvrSetup.AspectRatio; + + + ext_ctrl[4].id = V4L2_CID_MPEG_VIDEO_BITRATE; + ext_ctrl[4].value = PvrSetup.VideoBitrate * 1000; + + ext_ctrl[5].id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK; + ext_ctrl[5].value = 15000000; + + ext_ctrl[6].id = V4L2_CID_MPEG_STREAM_TYPE; + ext_ctrl[6].value = V4L2_MPEG_STREAM_TYPE_MPEG2_PS; + + for (uint i = 0; i < numCtrls; i++) + { + int value = ext_ctrl[i].value; + + ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG; + ctrls.count = 1; + ctrls.controls = ext_ctrl + i; + + if (IOCTL(video_fd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0) + { + log(0, "VIDIOC_S_EXT_CTRLS set to %d failed %d:%s", value, errno, strerror(errno)); + } + } + + /* Get controls */ + ext_ctrl[0].id = V4L2_CID_MPEG_VIDEO_GOP_SIZE; + ext_ctrl[0].value = 0; + + ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG; + ctrls.count = 1; + ctrls.controls = ext_ctrl; + + if (IOCTL(video_fd, VIDIOC_G_EXT_CTRLS, &ctrls) < 0) + { + log(0, "Get V4L2_CID_MPEG_VIDEO_GOP_SIZE failed, defaulting to 12 %d:%s", errno, strerror(errno)); + ext_ctrl[0].value = 12; + } + return true; } bool cPvrDevice::SetPicture(int brightness, int contrast, int saturation, int hue)