Index: configure =================================================================== --- configure (révision 18944) +++ configure (copie de travail) @@ -221,6 +221,7 @@ --disable-tv-v4l disable Video4Linux TV Interface support [autodetect] --disable-tv-v4l2 disable Video4Linux2 TV Interface support [autodetect] --disable-tv-bsdbt848 disable BSD BT848 Interface support [autodetect] + --disable-pvr disable Video4Linux2/IVTV PVR support [autodetect] --disable-rtc disable RTC (/dev/rtc) on Linux [autodetect] --disable-network disable network support (for: http/mms/rtp) [enable] --enable-winsock2 enable winsock2 usage [autodetect] @@ -1639,6 +1640,7 @@ _tv_v4l=auto _tv_v4l2=auto _tv_bsdbt848=auto +_pvr=auto _network=yes _winsock2=auto _smbsupport=auto @@ -1874,6 +1876,8 @@ --disable-tv-v4l) _tv_v4l=no ;; --enable-tv-v4l2) _tv_v4l2=yes ;; --disable-tv-v4l2) _tv_v4l2=no ;; + --enable-pvr) _pvr=yes ;; + --disable-pvr) _pvr=no ;; --enable-fastmemcpy) _fastmemcpy=yes ;; --disable-fastmemcpy) _fastmemcpy=no ;; --enable-network) _network=yes ;; @@ -6791,6 +6795,23 @@ echores "$_tv_v4l2" +echocheck "Video 4 Linux 2/IVTV PVR interface" +if test "$_pvr" = auto -o "$_pvr" = yes; then + _pvr=no + if test "$_tv" = yes -a "$_tv_v4l2" = yes && linux ; then + _pvr=yes + fi +fi +if test "$_pvr" = yes ; then + _def_pvr='#define HAVE_PVR 1' + _inputmodules="pvr $_inputmodules" +else + _noinputmodules="pvr $_noinputmodules" + _def_pvr='#undef HAVE_PVR' +fi +echores "$_pvr" + + echocheck "audio select()" if test "$_select" = no ; then _def_select='#undef HAVE_AUDIO_SELECT' @@ -7496,6 +7517,7 @@ TV_V4L = $_tv_v4l TV_V4L2 = $_tv_v4l2 TV_BSDBT848 = $_tv_bsdbt848 +PVR = $_pvr VCD = $_vcd HAVE_DVD = $_have_dvd DVDREAD = $_dvdread @@ -8034,6 +8056,9 @@ /* Enable *BSD BrookTree TV interface support */ $_def_tv_bsdbt848 +/* Enable Video 4 Linux 2/IVTV PVR support */ +$_def_pvr + /* Define if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ $_def_words_endian Index: cfg-common.h =================================================================== --- cfg-common.h (révision 18944) +++ cfg-common.h (copie de travail) @@ -135,6 +135,11 @@ #else {"tv", "MPlayer was compiled without TV interface support.\n", CONF_TYPE_PRINT, 0, 0, 0, NULL}, #endif +#ifdef HAVE_PVR + {"pvr", pvropts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, +#else + {"pvr", "MPlayer was compiled without V4L2/PVR interface support.\n", CONF_TYPE_PRINT, 0, 0, 0, NULL}, +#endif {"vivo", vivoopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, #ifdef HAS_DVBIN_SUPPORT {"dvbin", dvbin_opts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, @@ -418,6 +423,31 @@ }; #endif +#ifdef HAVE_PVR +extern int pvr_param_aspect_ratio; +extern int pvr_param_sample_rate; +extern int pvr_param_audio_layer; +extern int pvr_param_audio_bitrate; +extern char *pvr_param_audio_mode; +extern int pvr_param_bitrate; +extern char *pvr_param_bitrate_mode; +extern int pvr_param_bitrate_peak; +extern char *pvr_param_stream_type; + +m_option_t pvropts_conf[]={ + {"aspect", &pvr_param_aspect_ratio, CONF_TYPE_INT, 0, 1, 4, NULL}, + {"arate", &pvr_param_sample_rate, CONF_TYPE_INT, 0, 32000, 48000, NULL}, + {"alayer", &pvr_param_audio_layer, CONF_TYPE_INT, 0, 1, 2, NULL}, + {"abitrate", &pvr_param_audio_bitrate, CONF_TYPE_INT, 0, 32, 448, NULL}, + {"amode", &pvr_param_audio_mode, CONF_TYPE_STRING, 0, 0, 0, NULL}, + {"vbitrate", &pvr_param_bitrate, CONF_TYPE_INT, 0, 0, 0, NULL}, + {"vmode", &pvr_param_bitrate_mode, CONF_TYPE_STRING, 0, 0, 0, NULL}, + {"vpeak", &pvr_param_bitrate_peak, CONF_TYPE_INT, 0, 0, 0, NULL}, + {"fmt", &pvr_param_stream_type, CONF_TYPE_STRING, 0, 0, 0, NULL}, + {NULL, NULL, 0, 0, 0, 0, NULL} +}; +#endif + #ifdef HAS_DVBIN_SUPPORT #include "libmpdemux/dvbin.h" extern m_config_t dvbin_opts_conf[]; Index: libmpdemux/pvr.c =================================================================== --- libmpdemux/pvr.c (révision 0) +++ libmpdemux/pvr.c (révision 0) @@ -0,0 +1,1024 @@ +/* + * Copyright (C) 2006 Benjamin Zores + * Demuxer for WinTV PVR-150/250/350 (a.k.a IVTV) PVR cards. + * See http://ivtvdriver.org/index.php/Main_Page for more details on the + * cards supported by the ivtv driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mp_msg.h" +#include "help_mp.h" + +#include "stream.h" +#include "ivtv.h" +#include "tv.h" + +#define PVR_DEFAULT_DEVICE "/dev/video0" + +/* logging mechanisms */ +#define LOG_LEVEL_PVR "[pvr]" +#define LOG_LEVEL_V4L2 "[v4l2]" +#define LOG_LEVEL_IVTV "[ivtv]" + +/* IVTV driver settings (see http://ivtvdriver.org/index.php/Ivtvctl ) */ + +/* codec aspect ratio (1:1, 4:3, 16:9, 2.21:1) */ +#define PVR_ASPECT_RATIO_1_1 1 +#define PVR_ASPECT_RATIO_4_3 2 +#define PVR_ASPECT_RATIO_16_9 3 +#define PVR_ASPECT_RATIO_2_21_1 4 + +/* audio codec sample rate (32KHz, CD 44.1 KHz, AC97 48 KHz) */ +#define PVR_AUDIO_SAMPLE_RATE_44_1_KHZ 0x0000 +#define PVR_AUDIO_SAMPLE_RATE_48_KHZ 0x0001 +#define PVR_AUDIO_SAMPLE_RATE_32_KHZ 0x0002 + +/* audio codec layer (1 or 2) */ +#define PVR_AUDIO_LAYER_1 0x0004 +#define PVR_AUDIO_LAYER_2 0x0008 + +/* audio codec bitrate */ +#define PVR_AUDIO_BITRATE_32 0x0010 +#define PVR_AUDIO_BITRATE_L1_64 0x0020 +#define PVR_AUDIO_BITRATE_L1_96 0x0030 +#define PVR_AUDIO_BITRATE_L1_128 0x0040 +#define PVR_AUDIO_BITRATE_L1_160 0x0050 +#define PVR_AUDIO_BITRATE_L1_192 0x0060 +#define PVR_AUDIO_BITRATE_L1_224 0x0070 +#define PVR_AUDIO_BITRATE_L1_256 0x0080 +#define PVR_AUDIO_BITRATE_L1_288 0x0090 +#define PVR_AUDIO_BITRATE_L1_320 0x00A0 +#define PVR_AUDIO_BITRATE_L1_352 0x00B0 +#define PVR_AUDIO_BITRATE_L1_384 0x00C0 +#define PVR_AUDIO_BITRATE_L1_416 0x00D0 +#define PVR_AUDIO_BITRATE_L1_448 0x00E0 +#define PVR_AUDIO_BITRATE_L2_48 0x0020 +#define PVR_AUDIO_BITRATE_L2_56 0x0030 +#define PVR_AUDIO_BITRATE_L2_64 0x0040 +#define PVR_AUDIO_BITRATE_L2_80 0x0050 +#define PVR_AUDIO_BITRATE_L2_96 0x0060 +#define PVR_AUDIO_BITRATE_L2_112 0x0070 +#define PVR_AUDIO_BITRATE_L2_128 0x0080 +#define PVR_AUDIO_BITRATE_L2_160 0x0090 +#define PVR_AUDIO_BITRATE_L2_192 0x00A0 +#define PVR_AUDIO_BITRATE_L2_224 0x00B0 +#define PVR_AUDIO_BITRATE_L2_256 0x00C0 +#define PVR_AUDIO_BITRATE_L2_320 0x00D0 +#define PVR_AUDIO_BITRATE_L2_384 0x00E0 + +/* audio codec mode */ +#define PVR_AUDIO_MODE_ARG_STEREO "stereo" +#define PVR_AUDIO_MODE_ARG_JOINT_STEREO "joint_stereo" +#define PVR_AUDIO_MODE_ARG_DUAL "dual" +#define PVR_AUDIO_MODE_ARG_MONO "mono" +#define PVR_AUDIO_MODE_STEREO 0x0000 +#define PVR_AUDIO_MODE_JOINT_STEREO 0x0100 +#define PVR_AUDIO_MODE_DUAL 0x0200 +#define PVR_AUDIO_MODE_MONO 0x0300 + +/* video codec bitrate mode */ +#define PVR_VIDEO_BITRATE_MODE_ARG_VBR "vbr" +#define PVR_VIDEO_BITRATE_MODE_ARG_CBR "cbr" +#define PVR_VIDEO_BITRATE_MODE_VBR 0 +#define PVR_VIDEO_BITRATE_MODE_CBR 1 + +/* video codec stream type */ +#define PVR_VIDEO_STREAM_TYPE_PS "ps" +#define PVR_VIDEO_STREAM_TYPE_TS "ts" +#define PVR_VIDEO_STREAM_TYPE_MPEG1 "mpeg1" +#define PVR_VIDEO_STREAM_TYPE_DVD "dvd" +#define PVR_VIDEO_STREAM_TYPE_VCD "vcd" +#define PVR_VIDEO_STREAM_TYPE_SVCD "svcd" +#define PVR_VIDEO_STREAM_TYPE_DVD_S1 "dvds1" +#define PVR_VIDEO_STREAM_TYPE_DVD_S2 "dvds2" + +/* command line arguments */ +int pvr_param_aspect_ratio = 0; +int pvr_param_sample_rate = 0; +int pvr_param_audio_layer = 0; +int pvr_param_audio_bitrate = 0; +char *pvr_param_audio_mode = NULL; +int pvr_param_bitrate = 0; +char *pvr_param_bitrate_mode = NULL; +int pvr_param_bitrate_peak = 0; +char *pvr_param_stream_type = NULL; + +struct pvr_t { + int dev_fd; + char *video_dev; + + /* v4l2 params */ + int mute; + int input; + int normid; + int brightness; + int contrast; + int hue; + int saturation; + int width; + int height; + char *freq; + + /* ivtv params */ + int aspect; + int samplerate; + int layer; + int audio_rate; + int audio_mode; + int bitrate; + int bitrate_mode; + int bitrate_peak; + int stream_type; +}; + +static struct pvr_t * +pvr_init (void) +{ + struct pvr_t *pvr = NULL; + + pvr = (struct pvr_t *) malloc (sizeof (struct pvr_t)); + pvr->dev_fd = -1; + pvr->video_dev = strdup (PVR_DEFAULT_DEVICE); + + /* v4l2 params */ + pvr->mute = 0; + pvr->input = 0; + pvr->normid = -1; + pvr->brightness = 0; + pvr->contrast = 0; + pvr->hue = 0; + pvr->saturation = 0; + pvr->width = -1; + pvr->height = -1; + pvr->freq = NULL; + + /* ivtv params */ + pvr->aspect = -1; + pvr->samplerate = -1; + pvr->layer = -1; + pvr->audio_rate = -1; + pvr->audio_mode = -1; + pvr->bitrate = -1; + pvr->bitrate_mode = -1; + pvr->bitrate_peak = -1; + pvr->stream_type = -1; + + return pvr; +} + +static void +pvr_uninit (struct pvr_t *pvr) +{ + if (!pvr) + return; + + /* close V4L2 device */ + if (pvr->dev_fd) + close (pvr->dev_fd); + + if (pvr->video_dev) + free (pvr->video_dev); + if (pvr->freq) + free (pvr->freq); + free (pvr); +} + +/* IVTV layer */ + +static void +parse_ivtv_options (struct pvr_t *pvr) +{ + if (!pvr) + return; + + /* -pvr aspect=digit */ + if (pvr_param_aspect_ratio >= 1 && pvr_param_aspect_ratio <= 4) + pvr->aspect = pvr_param_aspect_ratio; + + /* -pvr arate=x */ + if (pvr_param_sample_rate != 0) + { + switch (pvr_param_sample_rate) + { + case 32000: + pvr->samplerate = PVR_AUDIO_SAMPLE_RATE_32_KHZ; + break; + case 44100: + pvr->samplerate = PVR_AUDIO_SAMPLE_RATE_44_1_KHZ; + break; + case 48000: + pvr->samplerate = PVR_AUDIO_SAMPLE_RATE_48_KHZ; + break; + default: + break; + } + } + + /* -pvr alayer=x */ + if (pvr_param_audio_layer == 1) + pvr->layer = PVR_AUDIO_LAYER_1; + else if (pvr_param_audio_layer == 2) + pvr->layer = PVR_AUDIO_LAYER_2; + + /* -pvr abitrate=x */ + if (pvr_param_audio_bitrate != 0) + { + /* set according to layer or use layer 1 by default if not specified */ + switch (pvr_param_audio_bitrate) + { + case 32: + pvr->audio_rate = PVR_AUDIO_BITRATE_32; + break; + case 48: + pvr->audio_rate = PVR_AUDIO_BITRATE_L2_48; + break; + case 56: + pvr->audio_rate = PVR_AUDIO_BITRATE_L2_56; + break; + case 64: + pvr->audio_rate = (pvr_param_audio_layer == 2) ? + PVR_AUDIO_BITRATE_L2_64 : PVR_AUDIO_BITRATE_L1_64; + break; + case 80: + pvr->audio_rate = PVR_AUDIO_BITRATE_L2_80; + break; + case 96: + pvr->audio_rate = (pvr_param_audio_layer == 2) ? + PVR_AUDIO_BITRATE_L2_96 : PVR_AUDIO_BITRATE_L1_96; + break; + case 112: + pvr->audio_rate = PVR_AUDIO_BITRATE_L2_112; + break; + case 128: + pvr->audio_rate = (pvr_param_audio_layer == 2) ? + PVR_AUDIO_BITRATE_L2_128 : PVR_AUDIO_BITRATE_L1_128; + break; + case 160: + pvr->audio_rate = (pvr_param_audio_layer == 2) ? + PVR_AUDIO_BITRATE_L2_160 : PVR_AUDIO_BITRATE_L1_160; + break; + case 192: + pvr->audio_rate = (pvr_param_audio_layer == 2) ? + PVR_AUDIO_BITRATE_L2_192 : PVR_AUDIO_BITRATE_L1_192; + break; + case 224: + pvr->audio_rate = (pvr_param_audio_layer == 2) ? + PVR_AUDIO_BITRATE_L2_224 : PVR_AUDIO_BITRATE_L1_224; + break; + case 256: + pvr->audio_rate = (pvr_param_audio_layer == 2) ? + PVR_AUDIO_BITRATE_L2_256 : PVR_AUDIO_BITRATE_L1_256; + break; + case 288: + pvr->audio_rate = PVR_AUDIO_BITRATE_L1_288; + break; + case 320: + pvr->audio_rate = (pvr_param_audio_layer == 2) ? + PVR_AUDIO_BITRATE_L2_320 : PVR_AUDIO_BITRATE_L1_320; + break; + case 352: + pvr->audio_rate = PVR_AUDIO_BITRATE_L1_352; + break; + case 384: + pvr->audio_rate = (pvr_param_audio_layer == 2) ? + PVR_AUDIO_BITRATE_L2_384 : PVR_AUDIO_BITRATE_L1_384; + break; + case 416: + pvr->audio_rate = PVR_AUDIO_BITRATE_L1_416; + break; + case 448: + pvr->audio_rate = PVR_AUDIO_BITRATE_L1_448; + break; + default: + break; + } + } + + /* -pvr amode=x */ + if (pvr_param_audio_mode) + { + if (!strcmp (pvr_param_audio_mode, PVR_AUDIO_MODE_ARG_STEREO)) + pvr->audio_mode = PVR_AUDIO_MODE_STEREO; + else if (!strcmp (pvr_param_audio_mode, PVR_AUDIO_MODE_ARG_JOINT_STEREO)) + pvr->audio_mode = PVR_AUDIO_MODE_JOINT_STEREO; + else if (!strcmp (pvr_param_audio_mode, PVR_AUDIO_MODE_ARG_DUAL)) + pvr->audio_mode = PVR_AUDIO_MODE_DUAL; + else if (!strcmp (pvr_param_audio_mode, PVR_AUDIO_MODE_ARG_MONO)) + pvr->audio_mode = PVR_AUDIO_MODE_MONO; + else /* for anything else, set to stereo */ + pvr->audio_mode = PVR_AUDIO_MODE_STEREO; + } + + /* -pvr vbitrate=x */ + if (pvr_param_bitrate) + pvr->bitrate = pvr_param_bitrate; + + /* -pvr vmode=x */ + if (pvr_param_bitrate_mode) + { + if (!strcmp (pvr_param_bitrate_mode, PVR_VIDEO_BITRATE_MODE_ARG_VBR)) + pvr->bitrate_mode = PVR_VIDEO_BITRATE_MODE_VBR; + else if (!strcmp (pvr_param_bitrate_mode, PVR_VIDEO_BITRATE_MODE_ARG_CBR)) + pvr->bitrate_mode = PVR_VIDEO_BITRATE_MODE_CBR; + else /* for anything else, set to VBR */ + pvr->bitrate_mode = PVR_VIDEO_BITRATE_MODE_VBR; + } + + /* -pvr vpeak=x */ + if (pvr_param_bitrate_peak) + pvr->bitrate_peak = pvr_param_bitrate_peak; + + /* -pvr fmt=x */ + if (pvr_param_stream_type) + { + if (!strcmp (pvr_param_stream_type, PVR_VIDEO_STREAM_TYPE_PS)) + pvr->stream_type = IVTV_STREAM_PS; + else if (!strcmp (pvr_param_stream_type, PVR_VIDEO_STREAM_TYPE_TS)) + pvr->stream_type = IVTV_STREAM_TS; + else if (!strcmp (pvr_param_stream_type, PVR_VIDEO_STREAM_TYPE_MPEG1)) + pvr->stream_type = IVTV_STREAM_MPEG1; + else if (!strcmp (pvr_param_stream_type, PVR_VIDEO_STREAM_TYPE_DVD)) + pvr->stream_type = IVTV_STREAM_DVD; + else if (!strcmp (pvr_param_stream_type, PVR_VIDEO_STREAM_TYPE_VCD)) + pvr->stream_type = IVTV_STREAM_VCD; + else if (!strcmp (pvr_param_stream_type, PVR_VIDEO_STREAM_TYPE_SVCD)) + pvr->stream_type = IVTV_STREAM_SVCD; + else if (!strcmp (pvr_param_stream_type, PVR_VIDEO_STREAM_TYPE_DVD_S1)) + pvr->stream_type = IVTV_STREAM_DVD_S1; + else if (!strcmp (pvr_param_stream_type, PVR_VIDEO_STREAM_TYPE_DVD_S2)) + pvr->stream_type = IVTV_STREAM_DVD_S2; + else /* for anything else, set to MPEG PS */ + pvr->stream_type = IVTV_STREAM_PS; + } +} + +static int +set_ivtv_settings (struct pvr_t *pvr) +{ + struct ivtv_ioctl_codec codec; + + if (!pvr) + return -1; + + if (pvr->dev_fd < 0) + return -1; + + /* get current settings */ + if (ioctl (pvr->dev_fd, IVTV_IOC_G_CODEC, &codec) < 0) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s can't get codec (%s).\n", LOG_LEVEL_IVTV, strerror (errno)); + return -1; + } + + /* set default encoding settings + * may be overlapped by user parameters + * Use VBR MPEG_PS encoding at 6 Mbps (peak at 9.6 Mbps) + * with 48 KHz L2 384 kbps audio. + */ + codec.aspect = PVR_ASPECT_RATIO_4_3; + codec.bitrate_mode = 0; + codec.bitrate = 6000000; + codec.bitrate_peak = 9600000; + codec.stream_type = IVTV_STREAM_PS; + codec.audio_bitmask = PVR_AUDIO_LAYER_2 + | PVR_AUDIO_BITRATE_L2_384 | PVR_AUDIO_SAMPLE_RATE_48_KHZ; + + /* set aspect ratio */ + if (pvr->aspect != -1) + codec.aspect = pvr->aspect; + + /* if user value is given, we need to reset audio bitmask */ + if ((pvr->samplerate != -1) || (pvr->layer != -1) + || (pvr->audio_rate != -1) || (pvr->audio_mode != -1)) + codec.audio_bitmask = 0; + + /* set audio samplerate */ + if (pvr->samplerate != -1) + codec.audio_bitmask |= pvr->samplerate; + + /* set audio layer */ + if (pvr->layer != -1) + codec.audio_bitmask |= pvr->layer; + + /* set audio bitrate */ + if (pvr->audio_rate != -1) + codec.audio_bitmask |= pvr->audio_rate; + + /* set audio mode */ + if (pvr->audio_mode != -1) + codec.audio_bitmask |= pvr->audio_mode; + + /* set video bitrate */ + if (pvr->bitrate != -1) + codec.bitrate = pvr->bitrate; + + /* set video bitrate mode */ + if (pvr->bitrate_mode != -1) + codec.bitrate_mode = pvr->bitrate_mode; + + /* set video bitrate peak */ + if (pvr->bitrate != -1) + codec.bitrate_peak = pvr->bitrate_peak; + + /* set video stream type */ + if (pvr->stream_type != -1) + codec.stream_type = pvr->stream_type; + + /* set new encoding settings */ + if (ioctl (pvr->dev_fd, IVTV_IOC_S_CODEC, &codec) < 0) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s can't set codec (%s).\n", LOG_LEVEL_IVTV, strerror (errno)); + return -1; + } + + return 0; +} + +/* V4L2 layer */ + +static void +parse_v4l2_tv_options (struct pvr_t *pvr) +{ + if (!pvr) + return; + + if (tv_param_device) + { + if (pvr->video_dev) + free (pvr->video_dev); + pvr->video_dev = strdup (tv_param_device); + } + + if (tv_param_noaudio) + pvr->mute = tv_param_noaudio; + + if (tv_param_input) + pvr->input = tv_param_input; + + if (tv_param_normid) + pvr->normid = tv_param_normid; + + if (tv_param_brightness) + pvr->brightness = tv_param_brightness; + + if (tv_param_contrast) + pvr->contrast = tv_param_contrast; + + if (tv_param_hue) + pvr->hue = tv_param_hue; + + if (tv_param_saturation) + pvr->saturation = tv_param_saturation; + + if (tv_param_width) + pvr->width = tv_param_width; + + if (tv_param_height) + pvr->height = tv_param_height; + + if (tv_param_freq) + pvr->freq = strdup (tv_param_freq); +} + +static int +set_v4l2_settings (struct pvr_t *pvr) +{ + if (!pvr) + return -1; + + if (pvr->dev_fd < 0) + return -1; + + /* -tv noaudio */ + if (pvr->mute) + { + struct v4l2_control ctrl; + ctrl.id = V4L2_CID_AUDIO_MUTE; + ctrl.value = 1; + if (ioctl (pvr->dev_fd, VIDIOC_S_CTRL, &ctrl) < 0) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s can't mute (%s).\n", LOG_LEVEL_V4L2, strerror (errno)); + return -1; + } + } + + /* -tv input=x */ + if (pvr->input != 0) + { + if (ioctl (pvr->dev_fd, VIDIOC_S_INPUT, &pvr->input) < 0) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s can't set input (%s)\n", LOG_LEVEL_V4L2, strerror (errno)); + return -1; + } + } + + /* -tv normid=x */ + if (pvr->normid != -1) + { + struct v4l2_standard std; + std.index = pvr->normid; + + if (ioctl (pvr->dev_fd, VIDIOC_ENUMSTD, &std) < 0) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s can't set norm (%s)\n", LOG_LEVEL_V4L2, strerror (errno)); + return -1; + } + + mp_msg (MSGT_DEMUX, MSGL_V, "[v4l2] set norm to %s\n", std.name); + + if (ioctl (pvr->dev_fd, VIDIOC_S_STD, &std.id) < 0) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s can't set norm (%s)\n", LOG_LEVEL_V4L2, strerror (errno)); + return -1; + } + } + + /* -tv brightness=x */ + if (pvr->brightness != 0) + { + struct v4l2_control ctrl; + ctrl.id = V4L2_CID_BRIGHTNESS; + ctrl.value = pvr->brightness; + + if (ctrl.value < 0) + ctrl.value = 0; + if (ctrl.value > 255) + ctrl.value = 255; + + if (ioctl (pvr->dev_fd, VIDIOC_S_CTRL, &ctrl) < 0) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s can't set brightness to %d (%s).\n", + LOG_LEVEL_V4L2, ctrl.value, strerror (errno)); + return -1; + } + } + + /* -tv contrast=x */ + if (pvr->contrast != 0) + { + struct v4l2_control ctrl; + ctrl.id = V4L2_CID_CONTRAST; + ctrl.value = pvr->contrast; + + if (ctrl.value < 0) + ctrl.value = 0; + if (ctrl.value > 127) + ctrl.value = 127; + + if (ioctl (pvr->dev_fd, VIDIOC_S_CTRL, &ctrl) < 0) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s can't set contrast to %d (%s).\n", + LOG_LEVEL_V4L2, ctrl.value, strerror (errno)); + return -1; + } + } + + /* -tv hue=x */ + if (pvr->hue != 0) + { + struct v4l2_control ctrl; + ctrl.id = V4L2_CID_HUE; + ctrl.value = pvr->hue; + + if (ctrl.value < -128) + ctrl.value = -128; + if (ctrl.value > 127) + ctrl.value = 127; + + if (ioctl (pvr->dev_fd, VIDIOC_S_CTRL, &ctrl) < 0) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s can't set hue to %d (%s).\n", + LOG_LEVEL_V4L2, ctrl.value, strerror (errno)); + return -1; + } + } + + /* -tv saturation=x */ + if (pvr->saturation != 0) + { + struct v4l2_control ctrl; + ctrl.id = V4L2_CID_SATURATION; + ctrl.value = pvr->saturation; + + if (ctrl.value < 0) + ctrl.value = 0; + if (ctrl.value > 127) + ctrl.value = 127; + + if (ioctl (pvr->dev_fd, VIDIOC_S_CTRL, &ctrl) < 0) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s can't set saturation to %d (%s).\n", + LOG_LEVEL_V4L2, ctrl.value, strerror (errno)); + return -1; + } + } + + /* -tv width=x:height=y */ + if (pvr->width && pvr->height) + { + struct v4l2_format vfmt; + vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vfmt.fmt.pix.width = pvr->width; + vfmt.fmt.pix.height = pvr->height; + + if (ioctl (pvr->dev_fd, VIDIOC_S_FMT, &vfmt) < 0) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s can't set resolution to %dx%d (%s).\n", + LOG_LEVEL_V4L2, pvr->width, pvr->height, strerror (errno)); + return -1; + } + } + + /* -tv freq=x */ + if (pvr->freq) + { + struct v4l2_frequency vf; + vf.tuner = 0; + vf.type = 0; + vf.frequency = strtol (pvr->freq, 0L, 0); + mp_msg (MSGT_DEMUX, MSGL_INFO, + "%s setting frequency to %d\n", LOG_LEVEL_V4L2, vf.frequency); + + if (ioctl (pvr->dev_fd, VIDIOC_S_FREQUENCY, &vf) < 0) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, "%s can't set frequency (%s).\n", + LOG_LEVEL_V4L2, strerror (errno)); + return -1; + } + } + + return 0; +} + +static int +v4l2_list_capabilities (struct pvr_t *pvr) +{ + struct v4l2_audio vaudio; + struct v4l2_standard vs; + struct v4l2_input vin; + int err = 0; + + if (!pvr) + return -1; + + if (pvr->dev_fd < 0) + return -1; + + /* list available video inputs */ + vin.index = 0; + err = 1; + mp_msg (MSGT_DEMUX, MSGL_INFO, + "%s Available video inputs: ", LOG_LEVEL_V4L2); + while (ioctl (pvr->dev_fd, VIDIOC_ENUMINPUT, &vin) >= 0) + { + err = 0; + mp_msg (MSGT_DEMUX, MSGL_INFO, "'#%d, %s' ", vin.index, vin.name); + vin.index++; + } + if (err) + { + mp_msg (MSGT_DEMUX, MSGL_INFO, "none\n"); + return -1; + } + else + mp_msg (MSGT_DEMUX, MSGL_INFO, "\n"); + + /* list available audio inputs */ + vaudio.index = 0; + err = 1; + mp_msg (MSGT_DEMUX, MSGL_INFO, + "%s Available audio inputs: ", LOG_LEVEL_V4L2); + while (ioctl (pvr->dev_fd, VIDIOC_ENUMAUDIO, &vaudio) >= 0) + { + err = 0; + mp_msg (MSGT_DEMUX, MSGL_INFO, "'#%d, %s' ", vaudio.index, vaudio.name); + vaudio.index++; + } + if (err) + { + mp_msg (MSGT_DEMUX, MSGL_INFO, "none\n"); + return -1; + } + else + mp_msg (MSGT_DEMUX, MSGL_INFO, "\n"); + + /* list available norms */ + vs.index = 0; + mp_msg (MSGT_DEMUX, MSGL_INFO, "%s Available norms: ", LOG_LEVEL_V4L2); + while (ioctl (pvr->dev_fd, VIDIOC_ENUMSTD, &vs) >= 0) + { + err = 0; + mp_msg (MSGT_DEMUX, MSGL_INFO, "'#%d, %s' ", vs.index, vs.name); + vs.index++; + } + if (err) + { + mp_msg (MSGT_DEMUX, MSGL_INFO, "none\n"); + return -1; + } + else + mp_msg (MSGT_DEMUX, MSGL_INFO, "\n"); + + return 0; +} + +static int +v4l2_display_settings (struct pvr_t *pvr) +{ + struct v4l2_audio vaudio; + struct v4l2_standard vs; + struct v4l2_input vin; + v4l2_std_id std; + int input; + + if (!pvr) + return -1; + + if (pvr->dev_fd < 0) + return -1; + + /* get current video input */ + if (ioctl (pvr->dev_fd, VIDIOC_G_INPUT, &input) == 0) + { + vin.index = input; + if (ioctl (pvr->dev_fd, VIDIOC_ENUMINPUT, &vin) < 0) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s can't get input (%s).\n", LOG_LEVEL_V4L2, strerror (errno)); + return -1; + } + else + mp_msg (MSGT_DEMUX, MSGL_INFO, + "%s Video input: %s\n", LOG_LEVEL_V4L2, vin.name); + } + else + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s can't get input (%s).\n", LOG_LEVEL_V4L2, strerror (errno)); + return -1; + } + + /* get current audio input */ + if (ioctl (pvr->dev_fd, VIDIOC_G_AUDIO, &vaudio) == 0) + { + vaudio.index = input; + if (ioctl (pvr->dev_fd, VIDIOC_ENUMAUDIO, &vaudio) < 0) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s can't get input (%s).\n", LOG_LEVEL_V4L2, strerror (errno)); + return -1; + } + else + mp_msg (MSGT_DEMUX, MSGL_INFO, + "%s Audio input: %s\n", LOG_LEVEL_V4L2, vaudio.name); + } + else + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s can't get input (%s).\n", LOG_LEVEL_V4L2, strerror (errno)); + return -1; + } + + /* get current video format */ + if (ioctl (pvr->dev_fd, VIDIOC_G_STD, &std) == 0) + { + vs.index = 0; + + while (ioctl (pvr->dev_fd, VIDIOC_ENUMSTD, &vs) >= 0) + { + if (vs.id == std) + { + mp_msg (MSGT_DEMUX, MSGL_INFO, + "%s Norm: %s.\n", LOG_LEVEL_V4L2, vs.name); + break; + } + vs.index++; + } + } + else + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s can't get norm (%s)\n", LOG_LEVEL_V4L2, strerror (errno)); + return -1; + } + + return 0; +} + +/* demuxer layer */ + +static void +pvr_stream_close (stream_t *stream) +{ + struct pvr_t *pvr; + + if (!stream) + return; + + pvr = (struct pvr_t *) stream->priv; + pvr_uninit (pvr); +} + +static int +pvr_stream_read (stream_t *stream, char *buffer, int size) +{ + struct pollfd pfds[1]; + struct pvr_t *pvr; + int rk, fd, pos; + + if (!stream || !buffer) + return 0; + + pvr = (struct pvr_t *) stream->priv; + fd = pvr->dev_fd; + pos = 0; + + if (fd < 0) + return 0; + + while (pos < size) + { + pfds[0].fd = fd; + pfds[0].events = POLLIN | POLLPRI; + + rk = size - pos; + + if (poll (pfds, 1, 500) <= 0) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s failed with errno %d when reading %d bytes\n", + LOG_LEVEL_PVR, errno, size-pos); + break; + } + + rk = read (fd, &buffer[pos], rk); + if (rk > 0) + { + pos += rk; + mp_msg (MSGT_DEMUX, MSGL_DBG3, + "%s read (%d) bytes\n", LOG_LEVEL_PVR, pos); + } + } + + if (!pos) + mp_msg (MSGT_DEMUX, MSGL_ERR, "%s read %d bytes\n", LOG_LEVEL_PVR, pos); + + return pos; +} + +static int +pvr_stream_open (stream_t *stream, int mode, void *opts, int *file_format) +{ + struct ivtv_ioctl_codec codec; + struct ivtv_driver_info info; + struct v4l2_capability vcap; + struct pvr_t *pvr = NULL; + + if (mode != STREAM_READ) + return STREAM_UNSUPORTED; + + pvr = pvr_init (); + + parse_v4l2_tv_options (pvr); + parse_ivtv_options (pvr); + + /* open device */ + pvr->dev_fd = open (pvr->video_dev, O_RDWR); + mp_msg (MSGT_DEMUX, MSGL_INFO, "[pvr] Using device %s\n", pvr->video_dev); + if (pvr->dev_fd == -1) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s error opening device %s\n", LOG_LEVEL_PVR, pvr->video_dev); + pvr_uninit (pvr); + return STREAM_ERROR; + } + + /* query capabilities (i.e test V4L2 support) */ + if (ioctl (pvr->dev_fd, VIDIOC_QUERYCAP, &vcap) < 0) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s device is not V4L2 compliant (%s).\n", + LOG_LEVEL_PVR, strerror (errno)); + pvr_uninit (pvr); + return STREAM_ERROR; + } + else + mp_msg (MSGT_DEMUX, MSGL_INFO, + "%s Detected %s\n", LOG_LEVEL_PVR, vcap.card); + + /* get codec and initialize card (i.e test IVTV support) */ + if (ioctl (pvr->dev_fd, IVTV_IOC_G_CODEC, &codec) < 0) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s device is not IVTV compliant (%s).\n", + LOG_LEVEL_PVR, strerror (errno)); + pvr_uninit (pvr); + return STREAM_ERROR; + } + + /* get ivtv driver info */ + if (ioctl (pvr->dev_fd, IVTV_IOC_G_DRIVER_INFO, &info) < 0) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s device is not IVTV compliant (%s).\n", + LOG_LEVEL_PVR, strerror (errno)); + pvr_uninit (pvr); + return STREAM_ERROR; + } + else + mp_msg (MSGT_DEMUX, MSGL_INFO, + "%s Detected ivtv driver: %s\n", LOG_LEVEL_PVR, info.comment); + + /* list V4L2 capabilities */ + if (v4l2_list_capabilities (pvr) == -1) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s can't get v4l2 capabilities\n", LOG_LEVEL_PVR); + pvr_uninit (pvr); + return STREAM_ERROR; + } + + /* apply V4L2 settings */ + if (set_v4l2_settings (pvr) == -1) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s can't set v4l2 settings\n", LOG_LEVEL_PVR); + pvr_uninit (pvr); + return STREAM_ERROR; + } + + /* apply IVTV settings */ + if (set_ivtv_settings (pvr) == -1) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s can't set ivtv settings\n", LOG_LEVEL_PVR); + pvr_uninit (pvr); + return STREAM_ERROR; + } + + /* display current V4L2 settings */ + if (v4l2_display_settings (pvr) == -1) + { + mp_msg (MSGT_DEMUX, MSGL_ERR, + "%s can't get v4l2 settings\n", LOG_LEVEL_PVR); + pvr_uninit (pvr); + return STREAM_ERROR; + } + + stream->priv = pvr; + stream->type = STREAMTYPE_PVR; + stream->fill_buffer = pvr_stream_read; + stream->close = pvr_stream_close; + + return STREAM_OK; +} + +stream_info_t stream_info_pvr = { + "PVR (V4L2/IVTV) Input", + "pvr", + "Benjamin Zores", + "", + pvr_stream_open, + { "pvr", NULL }, + NULL, + 1 +}; Index: libmpdemux/Makefile =================================================================== --- libmpdemux/Makefile (révision 18944) +++ libmpdemux/Makefile (copie de travail) @@ -74,6 +74,9 @@ endif ifeq ($(TV_V4L2),yes) SRCS += tvi_v4l2.c audio_in.c + ifeq ($(PVR),yes) + SRCS += pvr.c + endif endif ifeq ($(TV_V4L),yes) SRCS += tvi_v4l.c audio_in.c Index: libmpdemux/ivtv.h =================================================================== --- libmpdemux/ivtv.h (révision 0) +++ libmpdemux/ivtv.h (révision 0) @@ -0,0 +1,446 @@ +/* + Public ivtv API header + Copyright (C) 2003-2004 Kevin Thayer + + VBI portions: + Copyright (C) 2004 Hans Verkuil + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _LINUX_IVTV_H +#define _LINUX_IVTV_H + +/* Stream types */ +#define IVTV_STREAM_PS 0 +#define IVTV_STREAM_TS 1 +#define IVTV_STREAM_MPEG1 2 +#define IVTV_STREAM_PES_AV 3 +#define IVTV_STREAM_PES_V 5 +#define IVTV_STREAM_PES_A 7 +#define IVTV_STREAM_DVD 10 +#define IVTV_STREAM_VCD 11 +#define IVTV_STREAM_SVCD 12 +#define IVTV_STREAM_DVD_S1 13 +#define IVTV_STREAM_DVD_S2 14 + +#define IVTV_YUV_TYPE_HME12 0 /* Hauppauge macro block format */ +#define IVTV_YUV_TYPE_FOURCC_YV12 1 + +/* device ioctls should use the range 29-199 */ +#define IVTV_IOC_START_DECODE _IOW ('@', 29, struct ivtv_cfg_start_decode) +#define IVTV_IOC_STOP_DECODE _IOW ('@', 30, struct ivtv_cfg_stop_decode) +#define IVTV_IOC_G_SPEED _IOR ('@', 31, struct ivtv_speed) +#define IVTV_IOC_S_SPEED _IOW ('@', 32, struct ivtv_speed) +#define IVTV_IOC_DEC_STEP _IOW ('@', 33, int) +#define IVTV_IOC_DEC_FLUSH _IOW ('@', 34, int) +#define IVTV_IOC_PLAY _IO ('@', 37) +#define IVTV_IOC_PAUSE _IO ('@', 38) +#define IVTV_IOC_FRAMESYNC _IOR ('@', 39, struct ivtv_ioctl_framesync) +#define IVTV_IOC_GET_TIMING _IOR ('@', 40, struct ivtv_ioctl_framesync) +#define IVTV_IOC_S_SLOW_FAST _IOW ('@', 41, struct ivtv_slow_fast) +#define IVTV_IOC_S_START_DECODE _IOW ('@', 42, struct ivtv_cfg_start_decode) +#define IVTV_IOC_S_STOP_DECODE _IOW ('@', 43, struct ivtv_cfg_stop_decode) +#define IVTV_IOC_GET_FB _IOR ('@', 44, int) +#define IVTV_IOC_G_CODEC _IOR ('@', 48, struct ivtv_ioctl_codec) +#define IVTV_IOC_S_CODEC _IOW ('@', 49, struct ivtv_ioctl_codec) +#define IVTV_IOC_S_GOP_END _IOWR('@', 50, int) +#define IVTV_IOC_S_VBI_PASSTHROUGH _IOW ('@', 51, int) +#define IVTV_IOC_G_VBI_PASSTHROUGH _IOR ('@', 52, int) +#define IVTV_IOC_PASSTHROUGH _IOW ('@', 53, int) +#define IVTV_IOC_S_VBI_EMBED _IOW ('@', 54, int) +#define IVTV_IOC_G_VBI_EMBED _IOR ('@', 55, int) +#define IVTV_IOC_PAUSE_ENCODE _IO ('@', 56) +#define IVTV_IOC_RESUME_ENCODE _IO ('@', 57) +#define IVTV_IOC_DEC_SPLICE _IOW ('@', 58, int) +#define IVTV_IOC_DEC_FAST_STOP _IOW ('@', 59, int) +#define IVTV_IOC_PREP_FRAME_YUV _IOW ('@', 60, struct ivtvyuv_ioctl_dma_host_to_ivtv_args) +#define IVTV_IOC_G_YUV_INTERLACE _IOR ('@', 61, struct ivtv_ioctl_yuv_interlace) +#define IVTV_IOC_S_YUV_INTERLACE _IOW ('@', 62, struct ivtv_ioctl_yuv_interlace) +#define IVTV_IOC_G_PTS _IOR ('@', 63, uint64_t) + +// Note: You only append to this structure, you never reorder the members, +// you never play tricks with its alignment, you never change the size of +// anything. +#define IVTV_DRIVER_INFO_MAX_COMMENT_LENGTH 100 +struct ivtv_driver_info { + uint32_t size; // size of this structure + uint32_t version; // version bits 31-16 = major, 15-8 = minor, + // 7-0 = patchlevel + char comment[IVTV_DRIVER_INFO_MAX_COMMENT_LENGTH]; + uint32_t cardnr; // the ivtv card number (0-based) + uint32_t hw_flags; // hardware flags: which chips are used? +} __attribute__((packed)); + +#define IVTV_DRIVER_INFO_V1_SIZE 108 +#define IVTV_DRIVER_INFO_V2_SIZE 112 +#define IVTV_DRIVER_INFO_V3_SIZE 116 + +#define IVTV_IOC_G_DRIVER_INFO _IOWR('@', 100, struct ivtv_driver_info *) + +#define IVTV_HW_CX25840 (1 << 0) +#define IVTV_HW_SAA7115 (1 << 1) +#define IVTV_HW_SAA7127 (1 << 2) +#define IVTV_HW_MSP34XX (1 << 3) +#define IVTV_HW_TUNER (1 << 4) +#define IVTV_HW_WM8775 (1 << 5) +#define IVTV_HW_CS53L32A (1 << 6) +#define IVTV_HW_TVEEPROM (1 << 7) +#define IVTV_HW_SAA7114 (1 << 8) +#define IVTV_HW_TVAUDIO (1 << 9) +#define IVTV_HW_UPD64031A (1 << 10) +#define IVTV_HW_UPD6408X (1 << 11) +#define IVTV_HW_SAA717X (1 << 12) +#define IVTV_HW_WM8739 (1 << 13) +#define IVTV_HW_GPIO (1 << 14) + +#define IVTV_HW_SAA711X (IVTV_HW_SAA7115 | IVTV_HW_SAA7114) + +// Version info +// Note: never use the _INTERNAL versions of these macros + +// Internal version macros, don't use these +#define IVTV_VERSION_NUMBER_INTERNAL(name) name##_version_int +#define IVTV_VERSION_STRING_INTERNAL(name) name##_version_string +#define IVTV_VERSION_COMMENT_INTERNAL(name) name##_comment_string + +#define IVTV_VERSION_EXTERN_NUMBER_INTERNAL(name) \ + extern uint32_t IVTV_VERSION_NUMBER_INTERNAL(name) +#define IVTV_VERSION_EXTERN_STRING_INTERNAL(name) \ + extern const char * const IVTV_VERSION_STRING_INTERNAL(name) +#define IVTV_VERSION_EXTERN_COMMENT_INTERNAL(name) \ + extern const char * const IVTV_VERSION_COMMENT_INTERNAL(name) + +#define IVTV_VERSION_MAJOR_INTERNAL(name) \ + (0xFF & (IVTV_VERSION_NUMBER_INTERNAL(name) >> 16)) +#define IVTV_VERSION_MINOR_INTERNAL(name) \ + (0xFF & (IVTV_VERSION_NUMBER_INTERNAL(name) >> 8)) +#define IVTV_VERSION_PATCHLEVEL_INTERNAL(name) \ + (0xFF & (IVTV_VERSION_NUMBER_INTERNAL(name))) + +// External version macros +#define IVTV_VERSION_NUMBER(name) IVTV_VERSION_NUMBER_INTERNAL(name) +#define IVTV_VERSION_STRING(name) IVTV_VERSION_STRING_INTERNAL(name) +#define IVTV_VERSION_COMMENT(name) IVTV_VERSION_COMMENT_INTERNAL(name) +#define IVTV_VERSION_EXTERN_NUMBER(name) \ + IVTV_VERSION_EXTERN_NUMBER_INTERNAL(name) +#define IVTV_VERSION_EXTERN_STRING(name) \ + IVTV_VERSION_EXTERN_STRING_INTERNAL(name) +#define IVTV_VERSION_EXTERN_COMMENT(name) \ + IVTV_VERSION_EXTERN_COMMENT_INTERNAL(name) + +#define IVTV_VERSION_INFO_NAME ivtv_rev + +IVTV_VERSION_EXTERN_NUMBER(IVTV_VERSION_INFO_NAME); +IVTV_VERSION_EXTERN_STRING(IVTV_VERSION_INFO_NAME); +IVTV_VERSION_EXTERN_COMMENT(IVTV_VERSION_INFO_NAME); + +/* Custom v4l controls */ +#ifndef V4L2_CID_PRIVATE_BASE +#define V4L2_CID_PRIVATE_BASE 0x08000000 +#endif /* V4L2_CID_PRIVATE_BASE */ + +#define V4L2_CID_IVTV_FREQ (V4L2_CID_PRIVATE_BASE) +#define V4L2_CID_IVTV_ENC (V4L2_CID_PRIVATE_BASE + 1) +#define V4L2_CID_IVTV_BITRATE (V4L2_CID_PRIVATE_BASE + 2) +#define V4L2_CID_IVTV_MONO (V4L2_CID_PRIVATE_BASE + 3) +#define V4L2_CID_IVTV_JOINT (V4L2_CID_PRIVATE_BASE + 4) +#define V4L2_CID_IVTV_EMPHASIS (V4L2_CID_PRIVATE_BASE + 5) +#define V4L2_CID_IVTV_CRC (V4L2_CID_PRIVATE_BASE + 6) +#define V4L2_CID_IVTV_COPYRIGHT (V4L2_CID_PRIVATE_BASE + 7) +#define V4L2_CID_IVTV_GEN (V4L2_CID_PRIVATE_BASE + 8) + +#define V4L2_CID_IVTV_DEC_SMOOTH_FF (V4L2_CID_PRIVATE_BASE + 9) +#define V4L2_CID_IVTV_DEC_FR_MASK (V4L2_CID_PRIVATE_BASE + 10) +#define V4L2_CID_IVTV_DEC_SP_MUTE (V4L2_CID_PRIVATE_BASE + 11) +#define V4L2_CID_IVTV_DEC_FR_FIELD (V4L2_CID_PRIVATE_BASE + 12) +#define V4L2_CID_IVTV_DEC_AUD_SKIP (V4L2_CID_PRIVATE_BASE + 13) +#define V4L2_CID_IVTV_DEC_NUM_BUFFERS (V4L2_CID_PRIVATE_BASE + 14) +#define V4L2_CID_IVTV_DEC_PREBUFFER (V4L2_CID_PRIVATE_BASE + 15) + +struct ivtv_ioctl_framesync { + uint32_t frame; + uint64_t pts; + uint64_t scr; +}; + +struct ivtv_speed { + int scale; /* 1-?? (50 for now) */ + int smooth; /* Smooth mode when in slow/fast mode */ + int speed; /* 0 = slow, 1 = fast */ + int direction; /* 0 = forward, 1 = reverse (not supportd */ + int fr_mask; /* 0 = I, 1 = I,P, 2 = I,P,B 2 = default! */ + int b_per_gop; /* frames per GOP (reverse only) */ + int aud_mute; /* Mute audio while in slow/fast mode */ + int fr_field; /* 1 = show every field, 0 = show every frame */ + int mute; /* # of audio frames to mute on playback resume */ +}; + +struct ivtv_slow_fast { + int speed; /* 0 = slow, 1 = fast */ + int scale; /* 1-?? (50 for now) */ +}; + +struct ivtv_cfg_start_decode { + uint32_t gop_offset; /*Frames in GOP to skip before starting */ + uint32_t muted_audio_frames; /* #of audio frames to mute */ +}; + +struct ivtv_cfg_stop_decode { + int hide_last; /* 1 = show black after stop, + 0 = show last frame */ + uint64_t pts_stop; /* PTS to stop at */ +}; + +/* For use with IVTV_IOC_G_CODEC and IVTV_IOC_S_CODEC */ +struct ivtv_ioctl_codec { + uint32_t aspect; + uint32_t audio_bitmask; + uint32_t bframes; + uint32_t bitrate_mode; + uint32_t bitrate; + uint32_t bitrate_peak; + uint32_t dnr_mode; + uint32_t dnr_spatial; + uint32_t dnr_temporal; + uint32_t dnr_type; + uint32_t framerate; /* read only, ignored on write */ + uint32_t framespergop; /* read only, ignored on write */ + uint32_t gop_closure; + uint32_t pulldown; + uint32_t stream_type; +}; +struct ivtv_ioctl_yuv_interlace{ + int interlace_mode; /* Takes one of IVTV_YUV_MODE_xxxxxx values */ + int threshold; /* If mode is auto then if src_height <= this value treat as progressive otherwise treat as interlaced */ +}; +#define IVTV_YUV_MODE_INTERLACED 0 +#define IVTV_YUV_MODE_PROGRESSIVE 1 +#define IVTV_YUV_MODE_AUTO 2 + +/* Framebuffer external API */ + +struct ivtvfb_ioctl_state_info { + unsigned long status; + unsigned long alpha; +}; + +struct ivtvfb_ioctl_colorkey { + int state; + uint32_t colorKey; +}; + +struct ivtvfb_ioctl_blt_copy_args { + int x, y, width, height, source_offset, source_stride; +}; + +struct ivtvfb_ioctl_blt_fill_args { + int rasterop, alpha_mode, alpha_mask, width, height, x, y; + unsigned int destPixelMask, colour; + +}; + +struct ivtvfb_ioctl_dma_host_to_ivtv_args { + void *source; + unsigned long dest_offset; + int count; +}; + +struct ivtvyuv_ioctl_dma_host_to_ivtv_args { + void *y_source; + void *uv_source; + unsigned int yuv_type; + int src_x; + int src_y; + unsigned int src_w; + unsigned int src_h; + int dst_x; + int dst_y; + unsigned int dst_w; + unsigned int dst_h; + int srcBuf_width; + int srcBuf_height; +}; + +struct ivtvfb_ioctl_get_frame_buffer { + void *mem; + int size; + int sizex; + int sizey; +}; + +struct ivtv_osd_coords { + unsigned long offset; + unsigned long max_offset; + int pixel_stride; + int lines; + int x; + int y; +}; + +struct rectangle { + int x0; + int y0; + int x1; + int y1; +}; + +struct ivtvfb_ioctl_set_window { + int width; + int height; + int left; + int top; +}; + + + +/* Framebuffer ioctls should use the range 1 - 28 */ +#define IVTVFB_IOCTL_GET_STATE _IOR('@', 1, struct ivtvfb_ioctl_state_info) +#define IVTVFB_IOCTL_SET_STATE _IOW('@', 2, struct ivtvfb_ioctl_state_info) +#define IVTVFB_IOCTL_PREP_FRAME _IOW('@', 3, struct ivtvfb_ioctl_dma_host_to_ivtv_args) +#define IVTVFB_IOCTL_BLT_COPY _IOW('@', 4, struct ivtvfb_ioctl_blt_copy_args) +#define IVTVFB_IOCTL_GET_ACTIVE_BUFFER _IOR('@', 5, struct ivtv_osd_coords) +#define IVTVFB_IOCTL_SET_ACTIVE_BUFFER _IOW('@', 6, struct ivtv_osd_coords) +#define IVTVFB_IOCTL_GET_FRAME_BUFFER _IOR('@', 7, struct ivtvfb_ioctl_get_frame_buffer) +#define IVTVFB_IOCTL_BLT_FILL _IOW('@', 8, struct ivtvfb_ioctl_blt_fill_args) +#define IVTVFB_IOCTL_PREP_FRAME_BUF _IOW('@', 9, struct ivtvfb_ioctl_dma_host_to_ivtv_args) +#define IVTVFB_IOCTL_SET_WINDOW _IOW('@', 11, struct ivtvfb_ioctl_set_window) +#define IVTVFB_IOCTL_GET_COLORKEY _IOW('@', 12, struct ivtvfb_ioctl_colorkey) +#define IVTVFB_IOCTL_SET_COLORKEY _IOW('@', 13, struct ivtvfb_ioctl_colorkey) + +#define IVTVFB_STATUS_ENABLED (1 << 0) +#define IVTVFB_STATUS_GLOBAL_ALPHA (1 << 1) +#define IVTVFB_STATUS_LOCAL_ALPHA (1 << 2) +#define IVTVFB_STATUS_FLICKER_REDUCTION (1 << 3) + +#ifdef IVTV_INTERNAL +/* Do not use these structures and ioctls in code that you want to release. + Only to be used for testing and by the utilities ivtvctl, ivtvfbctl and fwapi. */ + +/* These are the VBI types as they appear in the embedded VBI private packets. + It is very likely that this will disappear and be replaced by the DVB standard. */ +#define IVTV_SLICED_TYPE_TELETEXT_B (1) +#define IVTV_SLICED_TYPE_CAPTION_525 (4) +#define IVTV_SLICED_TYPE_WSS_625 (5) +#define IVTV_SLICED_TYPE_VPS (7) + +#define IVTV_ENC_STREAM_TYPE_MPG 0 +#define IVTV_ENC_STREAM_TYPE_YUV 1 +#define IVTV_ENC_STREAM_TYPE_VBI 2 +#define IVTV_ENC_STREAM_TYPE_PCM 3 +#define IVTV_ENC_STREAM_TYPE_RAD 4 +#define IVTV_DEC_STREAM_TYPE_MPG 5 +#define IVTV_DEC_STREAM_TYPE_VBI 6 +#define IVTV_DEC_STREAM_TYPE_VOUT 7 +#define IVTV_DEC_STREAM_TYPE_YUV 8 +#define IVTV_DEC_STREAM_TYPE_OSD 9 + +struct ivtv_stream_info { + uint32_t size; + uint32_t type; +} __attribute__((packed)); + +#define IVTV_STREAM_INFO_V1_SIZE 8 +#define IVTV_IOC_G_STREAM_INFO _IOWR('@', 101, struct ivtv_stream_info *) + +#define IVTV_MBOX_MAX_DATA 16 + +struct ivtv_ioctl_fwapi { + uint32_t cmd; + uint32_t result; + int32_t args; + uint32_t data[IVTV_MBOX_MAX_DATA]; +}; + +struct ivtv_ioctl_event { + uint32_t type; + uint32_t mbox; + struct ivtv_ioctl_fwapi api; +}; + +struct ivtv_ioctl_register { + uint32_t i2c_id; /* I2C ID of the I2C chip. 0 for the I2C adapter. */ + unsigned long reg; + uint32_t val; +}; + +struct ivtv_msp_matrix { + int input; + int output; +}; + +/* Debug flags */ +#define IVTV_DBGFLG_WARN (1 << 0) +#define IVTV_DBGFLG_INFO (1 << 1) +#define IVTV_DBGFLG_API (1 << 2) +#define IVTV_DBGFLG_DMA (1 << 3) +#define IVTV_DBGFLG_IOCTL (1 << 4) +#define IVTV_DBGFLG_I2C (1 << 5) +#define IVTV_DBGFLG_IRQ (1 << 6) +#define IVTV_DBGFLG_DEC (1 << 7) +#define IVTV_DBGFLG_YUV (1 << 8) + +/* BLT RasterOps */ +#define IVTV_BLT_RASTER_ZERO 0 +#define IVTV_BLT_RASTER_NOTDEST_AND_NOTSRC 1 +#define IVTV_BLT_RASTER_NOTDEST_AND_SRC 2 +#define IVTV_BLT_RASTER_NOTDEST 3 +#define IVTV_BLT_RASTER_DEST_AND_NOTSRC 4 +#define IVTV_BLT_RASTER_NOTSRC 5 +#define IVTV_BLT_RASTER_DEST_XOR_SRC 6 +#define IVTV_BLT_RASTER_NOTDEST_OR_NOTSRC 7 + /* #define IVTV_BLT_RASTER_NOTDEST_AND_NOTSRC 8 *//* Same as 1 */ +#define IVTV_BLT_RASTER_DEST_XNOR_SRC 9 +#define IVTV_BLT_RASTER_SRC 10 +#define IVTV_BLT_RASTER_NOTDEST_OR_SRC 11 +#define IVTV_BLT_RASTER_DEST 12 +#define IVTV_BLT_RASTER_DEST_OR_NOTSRC 13 +#define IVTV_BLT_RASTER_DEST_OR_SRC 14 +#define IVTV_BLT_RASTER_ONE 15 + +/* BLT Alpha blending */ + +#define IVTV_BLT_ALPHABLEND_SRC 0x01 +#define IVTV_BLT_ALPHABLEND_DEST 0x10 +#define IVTV_BLT_ALPHABLEND_DEST_X_SRC 0x11 /* dest x src +1 , = zero if both zero */ + +#ifndef V4L2_COMMON_H_ +/* Routing definition, device dependent. It specifies which inputs (if any) + should be routed to which outputs (if any). */ +struct v4l2_routing { + __u32 input; + __u32 output; +}; +#endif + +/* Internal ioctls should use the range 200-255 */ +#define IVTV_IOC_S_DEBUG_LEVEL _IOWR('@', 200, int) +#define IVTV_IOC_G_DEBUG_LEVEL _IOR ('@', 201, int) +#define IVTV_IOC_RELOAD_FW _IO ('@', 202) +#define IVTV_IOC_ZCOUNT _IO ('@', 203) +#define IVTV_IOC_FWAPI _IOWR('@', 204, struct ivtv_ioctl_fwapi) +#define IVTV_IOC_EVENT_SETUP _IOWR('@', 205, struct ivtv_ioctl_event) +#define IVTV_IOC_G_DECODER_REG _IOWR('@', 206, struct ivtv_ioctl_register) +#define IVTV_IOC_S_DECODER_REG _IOW ('@', 207, struct ivtv_ioctl_register) +#define IVTV_IOC_G_ENCODER_REG _IOWR('@', 208, struct ivtv_ioctl_register) +#define IVTV_IOC_S_ENCODER_REG _IOW ('@', 209, struct ivtv_ioctl_register) +#define IVTV_IOC_S_AUDIO_ROUTING _IOW ('@', 210, struct v4l2_routing) +#define IVTV_IOC_G_ITVC_REG _IOWR('@', 211, struct ivtv_ioctl_register) +#define IVTV_IOC_S_ITVC_REG _IOW ('@', 212, struct ivtv_ioctl_register) +#define IVTV_IOC_RESET_IR _IO ('@', 213) + +#endif /* IVTV_INTERNAL */ + +#endif /* _LINUX_IVTV_H */ Index: libmpdemux/stream.c =================================================================== --- libmpdemux/stream.c (révision 18944) +++ libmpdemux/stream.c (copie de travail) @@ -54,6 +54,9 @@ #ifdef HAS_DVBIN_SUPPORT extern stream_info_t stream_info_dvb; #endif +#ifdef HAVE_PVR +extern stream_info_t stream_info_pvr; +#endif #ifdef HAVE_FTP extern stream_info_t stream_info_ftp; #endif @@ -101,6 +104,9 @@ #ifdef HAS_DVBIN_SUPPORT &stream_info_dvb, #endif +#ifdef HAVE_PVR + &stream_info_pvr, +#endif #ifdef HAVE_FTP &stream_info_ftp, #endif Index: libmpdemux/stream.h =================================================================== --- libmpdemux/stream.h (révision 18944) +++ libmpdemux/stream.h (copie de travail) @@ -21,6 +21,7 @@ #define STREAMTYPE_DVB 13 #define STREAMTYPE_VSTREAM 14 #define STREAMTYPE_SDP 15 +#define STREAMTYPE_PVR 16 #define STREAM_BUFFER_SIZE 2048