From owner-freebsd-multimedia@FreeBSD.ORG Sun Nov 20 07:16:02 2005 Return-Path: X-Original-To: freebsd-multimedia@freebsd.org Delivered-To: freebsd-multimedia@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7947916A41F for ; Sun, 20 Nov 2005 07:16:02 +0000 (GMT) (envelope-from dgreid@gmail.com) Received: from wproxy.gmail.com (wproxy.gmail.com [64.233.184.201]) by mx1.FreeBSD.org (Postfix) with ESMTP id B8BA543D46 for ; Sun, 20 Nov 2005 07:16:01 +0000 (GMT) (envelope-from dgreid@gmail.com) Received: by wproxy.gmail.com with SMTP id i5so625935wra for ; Sat, 19 Nov 2005 23:16:00 -0800 (PST) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:in-reply-to:mime-version:content-type:references; b=BsIbqE8vKkCq8rwnxMfTQY6E3t8kFFM3iV11/q5oZ3wSJrJyOiUUASg6CgvpyIoXPBFvD/qHVnjv+obuu618I44MCyfIGy8F+DAg6EErdnTOLgITiOYGoXhslY9op56MzP9Z2O94bPwGWSei0TCoNimXfwLgue1ImLt1HMJDqxU= Received: by 10.54.133.19 with SMTP id g19mr492990wrd; Sat, 19 Nov 2005 23:15:34 -0800 (PST) Received: by 10.54.118.1 with HTTP; Sat, 19 Nov 2005 23:16:00 -0800 (PST) Message-ID: Date: Sun, 20 Nov 2005 07:16:00 +0000 From: Dylan Reid To: freebsd-multimedia@freebsd.org In-Reply-To: MIME-Version: 1.0 References: Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Subject: Re: PVR250 MCE with cxm driver under 6.0 X-BeenThere: freebsd-multimedia@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Multimedia discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 20 Nov 2005 07:16:02 -0000 I have MythTV 0.18 running on FreeBSD 6.0(amd64). I had to merge some additional changes to the ones below to integrate the v4l2 support into the cxm driver to get myth to work. I also had to make a few minor changes to get myth to build properly. Dylan additional cxm patch: diff -u ../dev/cxm/cxm.c ./cxm.c --- ../dev/cxm/cxm.c Sun Nov 20 06:35:12 2005 +++ ./cxm.c Sun Nov 20 06:00:32 2005 @@ -80,6 +80,7 @@ #endif #include +#include #include @@ -333,7 +334,6 @@ 48000 }; - static const struct cxm_codec_profile *codec_profiles[] =3D { &vcd_ntsc_profile, @@ -848,7 +848,7 @@ fps =3D cxm_saa7115_detected_fps(sc); if (fps < 0) - return -1; + /* return -1; */ fps =3D 30; if (sc->profile->fps !=3D fps) { @@ -1762,8 +1762,10 @@ */ if (cxm_ir_init(sc) < 0) { device_printf(dev, "could not initialize IR remote\n"); +#ifndef PVR250_MCE error =3D ENXIO; goto fail; +#endif } sc->dec_mbx =3D -1; @@ -2192,8 +2194,9 @@ return ENXIO; } - if (sc->is_opened) - return EBUSY; + if (sc->is_opened) + /* allow it to be open'ed more than once. */ + return /* EBUSY */ 0; sc->is_opened =3D 1; sc->mpeg =3D 1; @@ -2334,6 +2337,81 @@ return 0; } +#define NUM_INPUTS 10 +struct v4l2_input tmk_inputs[NUM_INPUTS] =3D { + { + .index =3D 0, + .name =3D "Composite 0", + .type =3D V4L2_INPUT_TYPE_CAMERA, + .audioset =3D 1, + .tuner =3D 0, + .status =3D 0, + },{ + .index =3D 1, + .name =3D "Composite 1", + .type =3D V4L2_INPUT_TYPE_CAMERA, + .audioset =3D 1, + .tuner =3D 0, + .status =3D 0, + },{ + .index =3D 2, + .name =3D "Composite 2", + .type =3D V4L2_INPUT_TYPE_CAMERA, + .audioset =3D 1, + .tuner =3D 0, + .status =3D 0, + },{ + .index =3D 3, + .name =3D "Composite 3", + .type =3D V4L2_INPUT_TYPE_CAMERA, + .audioset =3D 1, + .tuner =3D 0, + .status =3D 0, + },{ + .index =3D 4, + .name =3D "Tuner 0", + .type =3D V4L2_INPUT_TYPE_TUNER, + .audioset =3D 0, + .tuner =3D 0, + .status =3D 0, + },{ + .index =3D 5, + .name =3D "Composite 4", + .type =3D V4L2_INPUT_TYPE_CAMERA, + .audioset =3D 1, + .tuner =3D 0, + .status =3D 0, + },{ + .index =3D 6, + .name =3D "S-Video 0", + .type =3D V4L2_INPUT_TYPE_CAMERA, + .audioset =3D 1, + .tuner =3D 0, + .status =3D 0, + },{ + .index =3D 7, + .name =3D "S-Video 1", + .type =3D V4L2_INPUT_TYPE_CAMERA, + .audioset =3D 1, + .tuner =3D 0, + .status =3D 0, + },{ + .index =3D 8, + .name =3D "S-Video 2", + .type =3D V4L2_INPUT_TYPE_CAMERA, + .audioset =3D 1, + .tuner =3D 0, + .status =3D 0, + },{ + .index =3D 9, + .name =3D "S-Video 3", + .type =3D V4L2_INPUT_TYPE_CAMERA, + .audioset =3D 1, + .tuner =3D 0, + .status =3D 0, + } +}; + /* * @@ -2369,6 +2447,391 @@ } switch (cmd) { + + /* Video 4 Linux like ioctl's... */ + case VIDIOC_QUERYCAP: + { + struct v4l2_capability *vcap =3D (struct v4l2_capability *)arg; + memset (vcap, 0, sizeof (*vcap)); + + /* driver name */ + strcpy(vcap->driver,"CXM"); + + /* card type */ + strcpy(vcap->card,"Hauppauge PVR-250"); + + /* bus info... */ + strcpy(vcap->bus_info, "PCI:0"); + + /* version */ + vcap->version =3D 0; + + /* capabilities */ + vcap->capabilities =3D (V4L2_CAP_VIDEO_CAPTURE|V4L2_CAP_TUNER| + V4L2_CAP_AUDIO|V4L2_CAP_READWRITE); + + break; + } + case VIDIOC_G_FMT: + { + struct v4l2_format *vfmt =3D (struct v4l2_format *)arg; + memset (vfmt, 0, sizeof (*vfmt)); + + vfmt->type =3D V4L2_BUF_TYPE_VIDEO_CAPTURE; + vfmt->fmt.pix.field =3D V4L2_FIELD_INTERLACED; + vfmt->fmt.pix.sizeimage =3D (128*1024); + vfmt->fmt.pix.width =3D sc->profile->width; + vfmt->fmt.pix.height =3D sc->profile->height; + + break; + } + case VIDIOC_S_FMT: + { + struct v4l2_format *vfmt =3D (struct v4l2_format *)arg; + + if (sc->encoding) + return EBUSY; + + if ((vfmt->fmt.pix.width % CXM_MACROBLOCK_WIDTH) + || (vfmt->fmt.pix.height % CXM_MACROBLOCK_HEIGHT)) + return EINVAL; + + /* + * Setting the width and height has the side effect of + * chosing between the VCD, SVCD, and DVD profiles. + */ + + for (i =3D 0; i < NUM_ELEMENTS(codec_profiles); i++) + if (codec_profiles[i]->width =3D=3D vfmt->fmt.pix.width + && codec_profiles[i]->height =3D=3D vfmt->fmt.pix.height) + break; + + if (i >=3D NUM_ELEMENTS(codec_profiles)) + { + /* need more codec profiles... just ignore for now */ + break; + /* return EINVAL; */ + } else { + sc->profile =3D codec_profiles[i]; + } + break; + } + case VIDIOC_S_STD: + /* should try to set this to something else than NTSC */ + break; + case VIDIOC_ENUMINPUT: + { + struct v4l2_input *vin =3D (struct v4l2_input *)arg; + + if ((vin->index < 0) || (vin->index >=3D NUM_INPUTS)) + return(-EINVAL); + + memcpy(vin, &tmk_inputs[vin->index], sizeof(struct v4l2_input)); + vin->std =3D V4L2_STD_NTSC; + vin->status =3D 0; + + break; + } + case VIDIOC_S_CTRL: + { + struct v4l2_control *vctrl =3D (struct v4l2_control *)arg; + + switch (vctrl->id) { + case V4L2_CID_BRIGHTNESS: + { + + if (vctrl->value < 0 || vctrl->value > 255) { + return(-EINVAL); + } + + if (cxm_saa7115_set_brightness(sc, vctrl->value) < 0) + return ENXIO; + + break; + } + case V4L2_CID_HUE: + { + if (vctrl->value < -128 || vctrl->value > 127) { + return(-EINVAL); + } + + if (cxm_saa7115_set_hue(sc, vctrl->value) < 0) + return ENXIO; + + break; + } + case V4L2_CID_SATURATION: + { + if (vctrl->value < 0 || vctrl->value > 127) { + return(-EINVAL); + } + + if (cxm_saa7115_set_chroma_saturation(sc, + vctrl->value) < 0) + return ENXIO; + + break; + } + case V4L2_CID_CONTRAST: + { + if (vctrl->value < 0 || vctrl->value > 127) { + return(-EINVAL); + } + + if (cxm_saa7115_set_contrast(sc, vctrl->value) < 0) + return ENXIO; + + break; + } + case V4L2_CID_AUDIO_VOLUME: + { + if (vctrl->value > 65535 || vctrl->value < 0) { + return(-EINVAL); + } + + break; + } + case V4L2_CID_AUDIO_MUTE: + { + if (vctrl->value) { + if (cxm_msp_mute(sc) < 0) return ENXIO; + } else { + if (cxm_msp_unmute(sc) < 0) return ENXIO; + } + + break; + } + default: + return(-EINVAL); + } + + + break; + } + case VIDIOC_QUERYCTRL: + { + struct v4l2_queryctrl *qctrl =3D (struct v4l2_queryctrl *)arg; + + qctrl->flags =3D V4L2_CTRL_FLAG_DISABLED; + + switch (qctrl->id) { + case V4L2_CID_BRIGHTNESS: + { + qctrl->type =3D V4L2_CTRL_TYPE_INTEGER; + strncpy(qctrl->name, "Brightness", 32); + qctrl->minimum =3D 0; + qctrl->maximum =3D 255; + qctrl->step =3D 0; + qctrl->default_value =3D 128; + qctrl->flags =3D 0; + qctrl->reserved[0] =3D 0; + qctrl->reserved[1] =3D 0; + break; + } + case V4L2_CID_HUE: + { + qctrl->type =3D V4L2_CTRL_TYPE_INTEGER; + strncpy(qctrl->name, "Hue", 32); + qctrl->minimum =3D -128; + qctrl->maximum =3D 127; + qctrl->step =3D 0; + qctrl->default_value =3D 0; + qctrl->flags =3D 0; + qctrl->reserved[0] =3D 0; + qctrl->reserved[1] =3D 0; + break; + } + case V4L2_CID_SATURATION: + { + qctrl->type =3D V4L2_CTRL_TYPE_INTEGER; + strncpy(qctrl->name, "Saturation", 32); + qctrl->minimum =3D 0; + qctrl->maximum =3D 127; + qctrl->step =3D 0; + qctrl->default_value =3D 64; + qctrl->flags =3D 0; + qctrl->reserved[0] =3D 0; + qctrl->reserved[1] =3D 0; + break; + } + case V4L2_CID_CONTRAST: + { + qctrl->type =3D V4L2_CTRL_TYPE_INTEGER; + strncpy(qctrl->name, "Contrast", 32); + qctrl->minimum =3D 0; + qctrl->maximum =3D 127; + qctrl->step =3D 0; + qctrl->default_value =3D 64; + qctrl->flags =3D 0; + qctrl->reserved[0] =3D 0; + qctrl->reserved[1] =3D 0; + break; + } + case V4L2_CID_AUDIO_VOLUME: + { + qctrl->type =3D V4L2_CTRL_TYPE_INTEGER; + strncpy(qctrl->name, "Volume", 32); + qctrl->minimum =3D 0; + qctrl->maximum =3D 65535; + qctrl->step =3D 0; + qctrl->default_value =3D 65535; + qctrl->flags =3D 0; + qctrl->reserved[0] =3D 0; + qctrl->reserved[1] =3D 0; + break; + } + case V4L2_CID_AUDIO_MUTE: + { + qctrl->type =3D V4L2_CTRL_TYPE_INTEGER; + strncpy(qctrl->name, "Mute", 32); + qctrl->minimum =3D 0; + qctrl->maximum =3D 1; + qctrl->step =3D 0; + qctrl->default_value =3D 1; + qctrl->flags =3D 0; + qctrl->reserved[0] =3D 0; + qctrl->reserved[1] =3D 0; + break; + } + default: + { + if (qctrl->id < V4L2_CID_BASE || + qctrl->id > V4L2_CID_LASTP1) + return EINVAL; + break; + } + } /* switch(qctrl->id) */ + + break; + } + case VIDIOC_S_INPUT: + { + int inp =3D *(int *)arg; + + source =3D cxm_unknown_source; + printf("set input to %d\n", inp); + switch (inp) { + default: + case 4: // tuner on 250 mce + source =3D cxm_tuner_source; + break; + + case 5: // composite on 250 mce + source =3D cxm_line_in_source_composite; + break; + } + + if (sc->encoding) { + + /* + * Switching between audio + video and audio only + * subtypes isn't supported while encoding. + */ + + if (source !=3D sc->source + && (source =3D=3D cxm_fm_source + || sc->source =3D=3D cxm_fm_source)) + return EBUSY; + } + + if (cxm_pause_encoder(sc) < 0) + return ENXIO; + + if (cxm_saa7115_select_source(sc, source) < 0) + return ENXIO; + if (cxm_msp_select_source(sc, source) < 0) + return ENXIO; + + sc->source =3D source; + + result =3D cxm_encoder_wait_for_lock(sc); + if (result < 0) + return ENXIO; + else if (result =3D=3D 0) + return EINVAL; + + if (cxm_unpause_encoder(sc) < 0) + return ENXIO; + break; + } + case VIDIOC_S_FREQUENCY: + { + struct v4l2_frequency *vf=3D(struct v4l2_frequency *)arg; + + /* Convert from Mhz * 16 to kHz */ + unsigned long freq =3D (vf->frequency * 1000) / 16; + int result; + + if (sc->source =3D=3D cxm_tuner_source) + if (cxm_pause_encoder(sc) < 0) + return ENXIO; + + if (cxm_tuner_select_frequency(sc, cxm_tuner_tv_freq_type, + freq) < 0) + return ENXIO; + + /* + * Explicitly wait for the tuner lock so we + * can indicate if there's a station present. + */ + if (cxm_tuner_wait_for_lock(sc) < 0) { + sc->tuner_signal =3D 0; + /* return EINVAL; */ + } + + result =3D cxm_encoder_wait_for_lock(sc); + if (result < 0) { + return ENXIO; + } else if (result =3D=3D 0) { + sc->tuner_signal =3D 0; + /* return EINVAL; */ + } else { + sc->tuner_signal =3D 65535; /* best possible signal */ + } + + if (sc->source =3D=3D cxm_tuner_source) + if (cxm_unpause_encoder(sc) < 0) + return ENXIO; + break; + } + case VIDIOC_G_TUNER: + { + struct v4l2_tuner *vt=3D(struct v4l2_tuner *)arg; + + vt->signal =3D sc->tuner_signal; + break; + } + case IVTV_IOC_G_CODEC: + { + struct ivtv_ioctl_codec *codec=3D(struct ivtv_ioctl_codec *)arg; + const struct cxm_codec_profile *cpp =3D sc->profile; + + codec->aspect =3D cpp->aspect; + codec->audio_bitmask =3D cpp->audio_sample_rate; + codec->bframes =3D cpp->gop.bframes; + codec->bitrate_mode =3D cpp->bitrate.mode; + codec->bitrate =3D cpp->bitrate.average; + codec->bitrate_peak =3D cpp->bitrate.peak; + codec->dnr_spatial =3D cpp->dnr.spatial; + codec->dnr_temporal =3D cpp->dnr.temporal; + codec->dnr_type =3D cpp->dnr.type; + codec->framerate =3D cpp->fps =3D=3D 30 ? 0 : 1; + codec->framespergop =3D cpp->gop.frames; + codec->gop_closure =3D cpp->gop.closure; + codec->pulldown =3D cpp->pulldown; + codec->stream_type =3D cpp->stream_type; + + break; + } + case IVTV_IOC_S_CODEC: + { + /* struct ivtv_ioctl_codec *codec=3D(struct ivtv_ioctl_codec *)arg; */ + + /* FIXME - need to figure out how to set this stuff */ + break; + } + + /* Brooktree ioctl's ... */ case BT848_GAUDIO: switch (cxm_msp_selected_source(sc)) { case cxm_tuner_source: @@ -2939,6 +3402,7 @@ break; default: + printf("unknown ioctl\n"); return ENOTTY; } diff -u ../dev/cxm/cxm.h ./cxm.h --- ../dev/cxm/cxm.h Sun Nov 20 06:35:12 2005 +++ ./cxm.h Mon Nov 14 06:35:35 2005 @@ -41,6 +41,8 @@ #define NUM_ELEMENTS(array) (sizeof(array) / sizeof(*array)) +#define PVR250_MCE // define for media center edition + /* * For simplicity several large buffers allocate during * driver attachment which normally occurs early on @@ -64,13 +66,13 @@ enum cxm_byte_order byte_order; }; -#define CXM_SG_BUFFERS 50 +#define CXM_SG_BUFFERS 100 struct cxm_buffer_pool { bus_dma_tag_t dmat; size_t offset; unsigned int read; - volatile unsigned int write; + unsigned int write; struct cxm_buffer bufs[CXM_SG_BUFFERS]; }; @@ -251,6 +253,7 @@ const struct cxm_tuner_channels *tuner_channels; int tuner_afc; unsigned long tuner_freq; + int tuner_signal; char msp_name[10]; Only in .: cxm_dec_fw.c Only in .: cxm_enc_fw.c Only in .: cxm_extract_fw Only in .: cxm_v4l.h diff -u ../dev/cxm/cxm_video.c ./cxm_video.c --- ../dev/cxm/cxm_video.c Sun Nov 20 06:35:12 2005 +++ ./cxm_video.c Mon Nov 14 06:09:33 2005 @@ -147,6 +147,21 @@ } }; +#ifdef PVR250_MCE +static struct cxm_saa7115_command +saa7115_select_line_in_composite =3D { + 3, + { + /* Amp plus anti-alias filter, CVBS from AI24 */ + { 0x02, 1, { 0xc5 } }, + /* Adaptive luminance comb filter */ + { 0x09, 1, { 0x40 } }, + + /* Enable AD2, audio clock, scaler, decoder */ + { 0x88, 1, { 0xb0 } } + } +}; +#else static struct cxm_saa7115_command saa7115_select_line_in_composite =3D { 3, @@ -160,6 +175,7 @@ { 0x88, 1, { 0x70 } } } }; +#endif static struct cxm_saa7115_command saa7115_select_line_in_svideo =3D { Here are the MythTv 0.18 changes: --- origmyth/mythtv-0.18.1/libs/libmythtv/videodev_myth.h Fri Jun 4 01:17:2= 3 2004 +++ mythtv-0.18.1/libs/libmythtv/videodev_myth.h Wed Nov 16 06:20:14 2005 @@ -3,7 +3,7 @@ #ifdef __FreeBSD__ #include -typedef unsigned long __u32; +typedef unsigned int __u32; typedef unsigned short __u16; typedef int __s32; typedef unsigned char __u8; --- origmyth/mythtv-0.18.1/libs/libmyth/DisplayResX.cpp Thu Apr 7 15:33:49 2005 +++ mythtv-0.18.1/libs/libmyth/DisplayResX.cpp Thu Nov 17 01:33:22 2005 @@ -2,19 +2,19 @@ #include #include -namespace X11 -{ +//namespace X11 +//{ #include #include #include #include -} +//} #include #include "DisplayResX.h" -using namespace X11; +//using namespace X11; static XRRScreenConfiguration *GetScreenConfig(Display*& display);--- origmyth/mythtv-0.18.1/configure Thu May 5 07:15:43 2005 +++ mythtv-0.18.1/configure Sat Nov 19 04:04:39 2005 @@ -359,6 +359,6 @@ extralibs=3D"$extralibs -lsocket -lnsl" ;; FreeBSD) -v4l=3D"no" +v4l=3D"yes" joystick_menu=3D"no" dv1394=3D"no" make=3D"gmake" On 11/9/05, Dylan Reid wrote: > > I have been trying to set up mythtv on FreeBSD 6.0 with an amd64 system. > First thing was to get the capture card to work. I first applied patches = for > ports/85433 and ports/87518. This got me compiling. In order to get the > module to load, I had to ignore the missing IR receiver. > > Next I wanted to use composite input, so I had to change which mode the > saa7115 was configured to when the composite input was selected. I could = not > find a good way to determine dynamically if the card is an MCE or not. I = did > not look into this too hard however. So i just went with the easiest > possible change. I did notice the Linux ivtv driver does not know the > difference. > > Below are the patches I made in case anyone else wants to use the cxm > driver with a 250 MCE. > > -Dylan > > --- cxm.c.orig Wed Nov 9 04:42:14 2005 > +++ cxm.c Wed Nov 9 04:51:56 2005 > @@ -1762,8 +1762,10 @@ > */ > if (cxm_ir_init(sc) < 0) { > device_printf(dev, "could not initialize IR remote\n"); > +#ifndef PVR250_MCE > error =3D ENXIO; > goto fail; > +#endif > } > > sc->dec_mbx =3D -1; > --- cxm.h.orig Wed Nov 9 04:59:32 2005 > +++ cxm.h Wed Nov 9 05:00:13 2005 > @@ -41,6 +41,8 @@ > > #define NUM_ELEMENTS(array) (sizeof(array) / sizeof(*array)) > > +#define PVR250_MCE // define for media center edition > + > /* > * For simplicity several large buffers allocate during > * driver attachment which normally occurs early on > --- cxm_video.c.orig Wed Nov 9 04:44:24 2005 > +++ cxm_video.c Wed Nov 9 05:21:44 2005 > @@ -147,6 +147,21 @@ > } > }; > > +#ifdef PVR250_MCE > +static struct cxm_saa7115_command > +saa7115_select_line_in_composite =3D { > + 3, > + { > + /* Amp plus anti-alias filter, CVBS from AI24 */ > + { 0x02, 1, { 0xc5 } }, > + /* Adaptive luminance comb filter */ > + { 0x09, 1, { 0x40 } }, > + > + /* Enable AD2, audio clock, scaler, decoder */ > + { 0x88, 1, { 0xb0 } } > + } > +}; > +#else > static struct cxm_saa7115_command > saa7115_select_line_in_composite =3D { > 3, > @@ -160,6 +175,7 @@ > { 0x88, 1, { 0x70 } } > } > }; > +#endif > > static struct cxm_saa7115_command > saa7115_select_line_in_svideo =3D { > >