Skip to content

Commit

Permalink
V4L/DVB (6346): ivtvfb: YUV output size fix when ivtvfb is not loaded
Browse files Browse the repository at this point in the history
If the ivtvfb module isn't loaded, the valid YUV output area should be set to
full-screen. This patch fixes the case where the valid output area was not
reset when the output broadcast format was changed from NTSC to PAL. This
resulted in output being limited to the top 480 lines of the display.

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>
  • Loading branch information
Ian Armstrong authored and Mauro Carvalho Chehab committed Oct 22, 2007
1 parent 0bfeb04 commit 195b125
Showing 1 changed file with 72 additions and 66 deletions.
138 changes: 72 additions & 66 deletions drivers/media/video/ivtv/ivtv-yuv.c
Original file line number Diff line number Diff line change
Expand Up @@ -857,95 +857,101 @@ void ivtv_yuv_work_handler (struct ivtv *itv)

static void ivtv_yuv_init (struct ivtv *itv)
{
struct yuv_playback_info *yi = &itv->yuv_info;

IVTV_DEBUG_YUV("ivtv_yuv_init\n");

/* Take a snapshot of the current register settings */
itv->yuv_info.reg_2834 = read_reg(0x02834);
itv->yuv_info.reg_2838 = read_reg(0x02838);
itv->yuv_info.reg_283c = read_reg(0x0283c);
itv->yuv_info.reg_2840 = read_reg(0x02840);
itv->yuv_info.reg_2844 = read_reg(0x02844);
itv->yuv_info.reg_2848 = read_reg(0x02848);
itv->yuv_info.reg_2854 = read_reg(0x02854);
itv->yuv_info.reg_285c = read_reg(0x0285c);
itv->yuv_info.reg_2864 = read_reg(0x02864);
itv->yuv_info.reg_2870 = read_reg(0x02870);
itv->yuv_info.reg_2874 = read_reg(0x02874);
itv->yuv_info.reg_2898 = read_reg(0x02898);
itv->yuv_info.reg_2890 = read_reg(0x02890);

itv->yuv_info.reg_289c = read_reg(0x0289c);
itv->yuv_info.reg_2918 = read_reg(0x02918);
itv->yuv_info.reg_291c = read_reg(0x0291c);
itv->yuv_info.reg_2920 = read_reg(0x02920);
itv->yuv_info.reg_2924 = read_reg(0x02924);
itv->yuv_info.reg_2928 = read_reg(0x02928);
itv->yuv_info.reg_292c = read_reg(0x0292c);
itv->yuv_info.reg_2930 = read_reg(0x02930);
itv->yuv_info.reg_2934 = read_reg(0x02934);
itv->yuv_info.reg_2938 = read_reg(0x02938);
itv->yuv_info.reg_293c = read_reg(0x0293c);
itv->yuv_info.reg_2940 = read_reg(0x02940);
itv->yuv_info.reg_2944 = read_reg(0x02944);
itv->yuv_info.reg_2948 = read_reg(0x02948);
itv->yuv_info.reg_294c = read_reg(0x0294c);
itv->yuv_info.reg_2950 = read_reg(0x02950);
itv->yuv_info.reg_2954 = read_reg(0x02954);
itv->yuv_info.reg_2958 = read_reg(0x02958);
itv->yuv_info.reg_295c = read_reg(0x0295c);
itv->yuv_info.reg_2960 = read_reg(0x02960);
itv->yuv_info.reg_2964 = read_reg(0x02964);
itv->yuv_info.reg_2968 = read_reg(0x02968);
itv->yuv_info.reg_296c = read_reg(0x0296c);
itv->yuv_info.reg_2970 = read_reg(0x02970);

itv->yuv_info.v_filter_1 = -1;
itv->yuv_info.v_filter_2 = -1;
itv->yuv_info.h_filter = -1;
yi->reg_2834 = read_reg(0x02834);
yi->reg_2838 = read_reg(0x02838);
yi->reg_283c = read_reg(0x0283c);
yi->reg_2840 = read_reg(0x02840);
yi->reg_2844 = read_reg(0x02844);
yi->reg_2848 = read_reg(0x02848);
yi->reg_2854 = read_reg(0x02854);
yi->reg_285c = read_reg(0x0285c);
yi->reg_2864 = read_reg(0x02864);
yi->reg_2870 = read_reg(0x02870);
yi->reg_2874 = read_reg(0x02874);
yi->reg_2898 = read_reg(0x02898);
yi->reg_2890 = read_reg(0x02890);

yi->reg_289c = read_reg(0x0289c);
yi->reg_2918 = read_reg(0x02918);
yi->reg_291c = read_reg(0x0291c);
yi->reg_2920 = read_reg(0x02920);
yi->reg_2924 = read_reg(0x02924);
yi->reg_2928 = read_reg(0x02928);
yi->reg_292c = read_reg(0x0292c);
yi->reg_2930 = read_reg(0x02930);
yi->reg_2934 = read_reg(0x02934);
yi->reg_2938 = read_reg(0x02938);
yi->reg_293c = read_reg(0x0293c);
yi->reg_2940 = read_reg(0x02940);
yi->reg_2944 = read_reg(0x02944);
yi->reg_2948 = read_reg(0x02948);
yi->reg_294c = read_reg(0x0294c);
yi->reg_2950 = read_reg(0x02950);
yi->reg_2954 = read_reg(0x02954);
yi->reg_2958 = read_reg(0x02958);
yi->reg_295c = read_reg(0x0295c);
yi->reg_2960 = read_reg(0x02960);
yi->reg_2964 = read_reg(0x02964);
yi->reg_2968 = read_reg(0x02968);
yi->reg_296c = read_reg(0x0296c);
yi->reg_2970 = read_reg(0x02970);

yi->v_filter_1 = -1;
yi->v_filter_2 = -1;
yi->h_filter = -1;

/* Set some valid size info */
itv->yuv_info.osd_x_offset = read_reg(0x02a04) & 0x00000FFF;
itv->yuv_info.osd_y_offset = (read_reg(0x02a04) >> 16) & 0x00000FFF;
yi->osd_x_offset = read_reg(0x02a04) & 0x00000FFF;
yi->osd_y_offset = (read_reg(0x02a04) >> 16) & 0x00000FFF;

/* Bit 2 of reg 2878 indicates current decoder output format
0 : NTSC 1 : PAL */
if (read_reg(0x2878) & 4)
itv->yuv_info.decode_height = 576;
yi->decode_height = 576;
else
itv->yuv_info.decode_height = 480;

/* If no visible size set, assume full size */
if (!itv->yuv_info.osd_vis_w)
itv->yuv_info.osd_vis_w = 720 - itv->yuv_info.osd_x_offset;
yi->decode_height = 480;

if (!itv->yuv_info.osd_vis_h) {
itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset;
if (!itv->osd_info) {
yi->osd_vis_w = 720 - yi->osd_x_offset;
yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
} else {
/* If output video standard has changed, requested height may
not be legal */
if (itv->yuv_info.osd_vis_h + itv->yuv_info.osd_y_offset > itv->yuv_info.decode_height) {
IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n",
itv->yuv_info.osd_vis_h + itv->yuv_info.osd_y_offset,
itv->yuv_info.decode_height);
itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset;
/* If no visible size set, assume full size */
if (!yi->osd_vis_w)
yi->osd_vis_w = 720 - yi->osd_x_offset;

if (!yi->osd_vis_h)
yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
else {
/* If output video standard has changed, requested height may
not be legal */
if (yi->osd_vis_h + yi->osd_y_offset > yi->decode_height) {
IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n",
yi->osd_vis_h + yi->osd_y_offset,
yi->decode_height);
yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
}
}
}

/* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
itv->yuv_info.blanking_ptr = kzalloc(720*16,GFP_KERNEL);
if (itv->yuv_info.blanking_ptr) {
itv->yuv_info.blanking_dmaptr = pci_map_single(itv->dev, itv->yuv_info.blanking_ptr, 720*16, PCI_DMA_TODEVICE);
}
yi->blanking_ptr = kzalloc(720*16, GFP_KERNEL);
if (yi->blanking_ptr)
yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
else {
itv->yuv_info.blanking_dmaptr = 0;
IVTV_DEBUG_WARN ("Failed to allocate yuv blanking buffer\n");
yi->blanking_dmaptr = 0;
IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n");
}

/* Enable YUV decoder output */
write_reg_sync(0x01, IVTV_REG_VDM);

set_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags);
atomic_set(&itv->yuv_info.next_dma_frame,0);
atomic_set(&yi->next_dma_frame, 0);
}

int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
Expand Down

0 comments on commit 195b125

Please sign in to comment.