diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2011-12-15 08:32:53 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-02-14 10:44:41 -0500 |
commit | debf80014fc1e8d02b3fd57e5fae0d315ac2cb04 (patch) | |
tree | b4275b68e02eab7865d5b61fd9ca4ac1ee9408a4 /drivers/media/video/ivtv/ivtv-controls.c | |
parent | 77bd4c0ff1671214ee026c175b4a5e1cc8776a0a (diff) |
[media] ivtv: implement new decoder controls
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-controls.c')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-controls.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c index b31ee1bceef8..e2901184db09 100644 --- a/drivers/media/video/ivtv/ivtv-controls.c +++ b/drivers/media/video/ivtv/ivtv-controls.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "ivtv-driver.h" | 21 | #include "ivtv-driver.h" |
22 | #include "ivtv-ioctl.h" | 22 | #include "ivtv-ioctl.h" |
23 | #include "ivtv-controls.h" | 23 | #include "ivtv-controls.h" |
24 | #include "ivtv-mailbox.h" | ||
24 | 25 | ||
25 | static int ivtv_s_stream_vbi_fmt(struct cx2341x_handler *cxhdl, u32 fmt) | 26 | static int ivtv_s_stream_vbi_fmt(struct cx2341x_handler *cxhdl, u32 fmt) |
26 | { | 27 | { |
@@ -99,3 +100,64 @@ struct cx2341x_handler_ops ivtv_cxhdl_ops = { | |||
99 | .s_video_encoding = ivtv_s_video_encoding, | 100 | .s_video_encoding = ivtv_s_video_encoding, |
100 | .s_stream_vbi_fmt = ivtv_s_stream_vbi_fmt, | 101 | .s_stream_vbi_fmt = ivtv_s_stream_vbi_fmt, |
101 | }; | 102 | }; |
103 | |||
104 | int ivtv_g_pts_frame(struct ivtv *itv, s64 *pts, s64 *frame) | ||
105 | { | ||
106 | u32 data[CX2341X_MBOX_MAX_DATA]; | ||
107 | |||
108 | if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) { | ||
109 | *pts = (s64)((u64)itv->last_dec_timing[2] << 32) | | ||
110 | (u64)itv->last_dec_timing[1]; | ||
111 | *frame = itv->last_dec_timing[0]; | ||
112 | return 0; | ||
113 | } | ||
114 | *pts = 0; | ||
115 | *frame = 0; | ||
116 | if (atomic_read(&itv->decoding)) { | ||
117 | if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) { | ||
118 | IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n"); | ||
119 | return -EIO; | ||
120 | } | ||
121 | memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing)); | ||
122 | set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags); | ||
123 | *pts = (s64)((u64) data[2] << 32) | (u64) data[1]; | ||
124 | *frame = data[0]; | ||
125 | /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/ | ||
126 | } | ||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | static int ivtv_g_volatile_ctrl(struct v4l2_ctrl *ctrl) | ||
131 | { | ||
132 | struct ivtv *itv = container_of(ctrl->handler, struct ivtv, hdl_out); | ||
133 | |||
134 | switch (ctrl->id) { | ||
135 | /* V4L2_CID_MPEG_VIDEO_DEC_PTS and V4L2_CID_MPEG_VIDEO_DEC_FRAME | ||
136 | control cluster */ | ||
137 | case V4L2_CID_MPEG_VIDEO_DEC_PTS: | ||
138 | return ivtv_g_pts_frame(itv, &itv->ctrl_pts->val64, | ||
139 | &itv->ctrl_frame->val64); | ||
140 | } | ||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | static int ivtv_s_ctrl(struct v4l2_ctrl *ctrl) | ||
145 | { | ||
146 | struct ivtv *itv = container_of(ctrl->handler, struct ivtv, hdl_out); | ||
147 | |||
148 | switch (ctrl->id) { | ||
149 | /* V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK and MULTILINGUAL_PLAYBACK | ||
150 | control cluster */ | ||
151 | case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK: | ||
152 | itv->audio_stereo_mode = itv->ctrl_audio_playback->val - 1; | ||
153 | itv->audio_bilingual_mode = itv->ctrl_audio_multilingual_playback->val - 1; | ||
154 | ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); | ||
155 | break; | ||
156 | } | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | const struct v4l2_ctrl_ops ivtv_hdl_out_ops = { | ||
161 | .s_ctrl = ivtv_s_ctrl, | ||
162 | .g_volatile_ctrl = ivtv_g_volatile_ctrl, | ||
163 | }; | ||