summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c')
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-encoder.c88
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;
}