diff options
Diffstat (limited to 'linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c')
-rw-r--r-- | linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c | 88 |
1 files changed, 49 insertions, 39 deletions
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c index 97931d3c4..6c66e258f 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c @@ -22,7 +22,7 @@ #include <linux/device.h> // for linux/firmware.h #include <linux/firmware.h> -#include "cx2341x.h" +#include <media/cx2341x.h> #include "pvrusb2-util.h" #include "pvrusb2-encoder.h" #include "pvrusb2-hdw-internal.h" @@ -268,50 +268,62 @@ static int pvr2_write_encoder_vcmd (struct pvr2_hdw *hdw, u8 cmd, int pvr2_encoder_configure(struct pvr2_hdw *hdw) { int ret = 0, audio, i; - int vd_std = hdw->controls[PVR2_CID_VIDEOSTANDARD].value; - int height = hdw->controls[PVR2_CID_VRES].value; - int width = hdw->controls[PVR2_CID_HRES].value; - int height_full = !hdw->controls[PVR2_CID_INTERLACE].value; + v4l2_std_id vd_std = hdw->std_mask_cur; + int height = hdw->res_ver_val; + int width = hdw->res_hor_val; + int height_full = !hdw->interlace_val; int is_30fps, is_ntsc; - switch (vd_std) { - case PVR2_CVAL_VIDEOSTANDARD_NTSC_M: + if (vd_std & V4L2_STD_NTSC) { is_ntsc=1; is_30fps=1; - break; - case PVR2_CVAL_VIDEOSTANDARD_PAL_M: + } else if (vd_std & V4L2_STD_PAL_M) { is_ntsc=0; is_30fps=1; - break; - default: + } else { is_ntsc=0; is_30fps=0; - break; } pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure"); - /* set stream output port. */ + /* set stream output port. Some notes here: The ivtv-derived + encoder documentation says that this command only gets a + single argument. However the Windows driver for the model + 29xxx series hardware has been sending 0x01 as a second + argument, while the Windows driver for the model 24xxx + series hardware has been sending 0x02 as a second argument. + Confusing matters further are the observations that 0x01 + for that second argument simply won't work on the 24xxx + hardware, while 0x02 will work on the 29xxx - except that + when we use 0x02 then xawtv breaks due to a loss of + synchronization with the mpeg packet headers. While xawtv + should be fixed to let it resync better (I did try to + contact Gerd about this but he has not answered), it has + also been determined that sending 0x00 as this mystery + second argument seems to work on both hardware models AND + xawtv works again. So we're going to send 0x00. */ ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_OUTPUT_PORT, 2, - 0x01, 0x01); + 0x01, 0x00); /* set the Program Index Information. We want I,P,B frames (max 400) */ ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_PGM_INDEX_INFO, 2, 0x07, 0x0190); - /* NOTE : windows driver sends some 0xdc */ - - /* Mike Isely <isely@pobox.com> 19-Jun-2005 I've confirmed - that the Windows driver seems to issue these commands, but - right now I have no idea what these do (and neither does - the ivtv driver). But, if I leave them in, then mplayer - goes nuts with xrun errors. So for now we don't do this. - It sure would be nice to know what these are for. */ -#if 0 - ret |= pvr2_write_encoder_vcmd(hdw, 0xdc, 1, 5); - ret |= pvr2_write_encoder_vcmd(hdw, 0xdc, 2, 3, 1); - ret |= pvr2_write_encoder_vcmd(hdw, 0xdc, 1, 8); + /* NOTE : windows driver sends these */ + /* Mike Isely <isely@pobox.com> 7-Mar-2006 The windows driver + sends the following commands but if we do the same then + many apps are no longer able to read the video stream. + Leaving these out seems to do no harm at all, so they're + commented out for that reason. */ +#ifdef notdef + ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 5,0,0,0); + ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 3,1,0,0); + ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 8,0,0,0); + ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 4,1,0,0); + ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4, 0,3,0,0); + ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_MISC,4,15,0,0,0); #endif /* Strange compared to ivtv data. */ @@ -373,9 +385,9 @@ int pvr2_encoder_configure(struct pvr2_hdw *hdw) /* set video bitrate */ ret |= pvr2_write_encoder_vcmd( hdw, CX2341X_ENC_SET_BIT_RATE, 3, - (hdw->controls[PVR2_CID_VBR].value ? 1 : 0), - hdw->controls[PVR2_CID_AVERAGEVIDEOBITRATE].value, - (u32) (hdw->controls[PVR2_CID_PEAKVIDEOBITRATE].value) / 400); + (hdw->vbr_val ? 1 : 0), + hdw->videobitrate_val, + hdw->videopeak_val / 400); /* setup GOP structure (GOP size = 0f or 0c, 3-1 = 2 B-frames) */ ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_SET_GOP_PROPERTIES, 2, is_30fps ? 0x0f : 0x0c, 0x03); @@ -387,13 +399,11 @@ int pvr2_encoder_configure(struct pvr2_hdw *hdw) ret |= pvr2_write_encoder_vcmd(hdw,CX2341X_ENC_SET_GOP_CLOSURE,1,0); /* set audio stream properties 0x40b9? 0100 0000 1011 1001 */ - audio = (pvr_tbl_audiobitrate[hdw->controls[ - PVR2_CID_AUDIOBITRATE].value] | - pvr_tbl_srate[hdw->controls[PVR2_CID_SRATE].value] | - hdw->controls[PVR2_CID_AUDIOLAYER].value << 2 | - (hdw->controls[PVR2_CID_AUDIOCRC].value ? 1 << 14 : 0) | - pvr_tbl_emphasis[hdw->controls[ - PVR2_CID_AUDIOEMPHASIS].value]); + audio = (pvr_tbl_audiobitrate[hdw->audiobitrate_val] | + pvr_tbl_srate[hdw->srate_val] | + hdw->audiolayer_val << 2 | + (hdw->audiocrc_val ? 1 << 14 : 0) | + pvr_tbl_emphasis[hdw->audioemphasis_val]); ret |= pvr2_write_encoder_vcmd(hdw,CX2341X_ENC_SET_AUDIO_PROPERTIES,1, audio); @@ -419,7 +429,7 @@ int pvr2_encoder_configure(struct pvr2_hdw *hdw) ret |= pvr2_write_encoder_vcmd(hdw, CX2341X_ENC_INITIALIZE_INPUT, 0); if (!ret) { - hdw->subsys_enabled_mask |= PVR2_SUBSYS_ENC_CFG; + hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_CFG); } return ret; @@ -447,7 +457,7 @@ int pvr2_encoder_start(struct pvr2_hdw *hdw) 0,0x13); } if (!status) { - hdw->subsys_enabled_mask |= PVR2_SUBSYS_ENC_RUN; + hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_RUN); } return status; } @@ -477,7 +487,7 @@ int pvr2_encoder_stop(struct pvr2_hdw *hdw) pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000); if (!status) { - hdw->subsys_enabled_mask &= ~PVR2_SUBSYS_ENC_RUN; + hdw->subsys_enabled_mask &= ~(1<<PVR2_SUBSYS_B_ENC_RUN); } return status; } |