aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv/ivtv-yuv.c
diff options
context:
space:
mode:
authorIan Armstrong <ian@iarmst.demon.co.uk>2007-11-05 12:27:09 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-01-25 16:03:11 -0500
commit77aded6ba51f01335840ce8e18b413067810b68e (patch)
tree2763dd287dd0f40bed5a1ba5262e0e13f58bf4e4 /drivers/media/video/ivtv/ivtv-yuv.c
parent3b5c1c8e71eb8fe2297a5884db59108e3c8b44c5 (diff)
V4L/DVB (6717): ivtv: Initial merge of video48 yuv handling into the IVTV_IOC_DMA_FRAME framework
Previously, all yuv data written to /dev/video48 had only basic support with no double buffering to avoid display tearing. With this patch, yuv frames written to video48 are now handled by the existing IVTV_IOC_DMA_FRAME framework. As such, the frames are hardware buffered to avoid tearing, and honour scaling mode & field order options. Unlike the proprietary IVTV_IOC_DMA_FRAME ioctl, all parameters are controlled by the V4L2 API. Due to mpeg & yuv output restrictions being different, their V4L2 output controls have been separated. To control the yuv output, the V4L2 calls must be done via video48. If the ivtvfb module is loaded, there will be one side effect to this merge. The yuv output window will be constrained to the visible framebuffer area. In the event that a virtual framebuffer size is being used, the limit to the output size will be the virtual dimensions, but only the portion that falls within the currently visible area of the framebuffer will be shown. Like the IVTV_IOC_DMA_FRAME ioctl, the supplied frames must be padded to 720 pixels wide. However the height must only be padded up the nearest multiple of 32. This would mean an image of 102 lines must be padded to 128. As long as the true source image size is given, the padding will not be visible in the final output. Signed-off-by: Ian Armstrong <ian@iarmst.demon.co.uk> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-yuv.c')
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c58
1 files changed, 51 insertions, 7 deletions
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index cd42db9b5a15..711ce5b5a20f 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -1035,17 +1035,11 @@ void ivtv_yuv_frame_complete(struct ivtv *itv)
1035 (itv->yuv_info.draw_frame + 1) % IVTV_YUV_BUFFERS); 1035 (itv->yuv_info.draw_frame + 1) % IVTV_YUV_BUFFERS);
1036} 1036}
1037 1037
1038int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args) 1038int ivtv_yuv_udma_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
1039{ 1039{
1040 DEFINE_WAIT(wait); 1040 DEFINE_WAIT(wait);
1041 int rc = 0; 1041 int rc = 0;
1042 int got_sig = 0; 1042 int got_sig = 0;
1043
1044 IVTV_DEBUG_INFO("yuv_prep_frame\n");
1045
1046 ivtv_yuv_next_free(itv);
1047 ivtv_yuv_setup_frame(itv, args);
1048
1049 /* DMA the frame */ 1043 /* DMA the frame */
1050 mutex_lock(&itv->udma.lock); 1044 mutex_lock(&itv->udma.lock);
1051 1045
@@ -1084,6 +1078,56 @@ int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
1084 return rc; 1078 return rc;
1085} 1079}
1086 1080
1081/* Setup frame according to V4L2 parameters */
1082void ivtv_yuv_setup_stream_frame(struct ivtv *itv)
1083{
1084 struct yuv_playback_info *yi = &itv->yuv_info;
1085 struct ivtv_dma_frame dma_args;
1086
1087 ivtv_yuv_next_free(itv);
1088
1089 /* Copy V4L2 parameters to an ivtv_dma_frame struct... */
1090 dma_args.y_source = 0L;
1091 dma_args.uv_source = 0L;
1092 dma_args.src.left = 0;
1093 dma_args.src.top = 0;
1094 dma_args.src.width = yi->v4l2_src_w;
1095 dma_args.src.height = yi->v4l2_src_h;
1096 dma_args.dst = yi->main_rect;
1097 dma_args.src_width = yi->v4l2_src_w;
1098 dma_args.src_height = yi->v4l2_src_h;
1099
1100 /* ... and use the same setup routine as ivtv_yuv_prep_frame */
1101 ivtv_yuv_setup_frame(itv, &dma_args);
1102
1103 if (!itv->dma_data_req_offset)
1104 itv->dma_data_req_offset = yuv_offset[yi->draw_frame];
1105}
1106
1107/* Attempt to dma a frame from a user buffer */
1108int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void *src)
1109{
1110 struct yuv_playback_info *yi = &itv->yuv_info;
1111 struct ivtv_dma_frame dma_args;
1112
1113 ivtv_yuv_setup_stream_frame(itv);
1114
1115 /* We only need to supply source addresses for this */
1116 dma_args.y_source = src;
1117 dma_args.uv_source = src + 720 * ((yi->v4l2_src_h + 31) & ~31);
1118 return ivtv_yuv_udma_frame(itv, &dma_args);
1119}
1120
1121/* IVTV_IOC_DMA_FRAME ioctl handler */
1122int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
1123{
1124 IVTV_DEBUG_INFO("yuv_prep_frame\n");
1125
1126 ivtv_yuv_next_free(itv);
1127 ivtv_yuv_setup_frame(itv, args);
1128 return ivtv_yuv_udma_frame(itv, args);
1129}
1130
1087void ivtv_yuv_close(struct ivtv *itv) 1131void ivtv_yuv_close(struct ivtv *itv)
1088{ 1132{
1089 int h_filter, v_filter_1, v_filter_2; 1133 int h_filter, v_filter_1, v_filter_2;