This documents how to convert the ivtv-proprietry ioctls to the new V4L2 ioctls.

----------------------------------------

ioctl IVTVFB_IOCTL_SET_WINDOW: use VIDIOC_S_CROP instead with type set to
V4L2_BUF_TYPE_VIDEO_OUTPUT. The v4l2_rect c contains the top/left position
and the size to which the video is scaled.

----------------------------------------

ioctl IVTV_IOC_S/G_YUV_INTERLACE: Use VIDIOC_S/G_FMT with type V4L2_BUF_TYPE_VIDEO_OUTPUT.
The 'field' member of v4l2_pix_format contains the current or can be set to the field order.

IVTV_YUV_MODE_INTERLACED | IVTV_YUV_SYNC_EVEN maps to V4L2_FIELD_INTERLACED_TB.
IVTV_YUV_MODE_INTERLACED | IVTV_YUV_SYNC_ODD maps to V4L2_FIELD_INTERLACED_BT.
IVTV_YUV_MODE_PROGRESSIVE maps to V4L2_FIELD_NONE.
IVTV_YUV_MODE_AUTO maps to V4L2_FIELD_ANY (the default).

It is no longer possible to set the threshold for the 'auto' mode. That is done by the driver. 

---------------------------------------

The chromakey and local/global alpha settings of the framebuffer are now set
using the v4l2 overlay functionality.

A new buffer type V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY was added to support output
overlays. By specifying this type with VIDIOC_S_FMT and filling in the chromakey and/or
global_alpha values of the v4l2_window struct you can change the chromakey
and global alpha.

To enable/disable chromakey/global alpha/local alpha in the framebuffer you
call VIDIOC_S_FBUF and specify the new flags V4L2_FBUF_FLAG_LOCAL_ALPHA and
V4L2_FBUF_FLAG_GLOBAL_ALPHA. The corresponding capabilities V4L2_FBUF_CAP_LOCAL_ALPHA
and V4L2_FBUF_CAP_GLOBAL_ALPHA are also added.

All this replaces the following old ioctls:

IVTVFB_IOCTL_GET_COLORKEY
IVTVFB_IOCTL_SET_COLORKEY
IVTVFB_IOCTL_GET_ALPHA
IVTVFB_IOCTL_SET_ALPHA
IVTVFB_IOCTL_GET_STATE
IVTVFB_IOCTL_SET_STATE

---------------------------------------

ioctl IVTV_IOC_PREP_FRAME_YUV has been replaced with IVTV_IOC_DMA_FRAME. This is
still an ioctl specific to ivtv. It might or might not be replaced by something
better in the future. The media/ivtv.h header contains clear instructions on the
use of this ioctl. Make sure you fill in the new 'type' field!

---------------------------------------

ivtv now uses the linux/dvb/audio.h and linux/dvb/video.h ioctls for commanding
the MPEG decoder (PVR-350). In order to support everything ivtv needs those
ioctls have been extended as well. So you will have to include these headers
to be able to command the MPEG decoder.

--------------------------------------

ioctls IVTV_IOC_S_VBI_PASSTHROUGH and IVTV_IOC_G_VBI_PASSTHROUGH are removed.
By default the driver attempts to passthrough VBI data whenever possible in
passthrough mode.

-------------------------------------

ioctl IVTV_IOC_DEC_FLUSH is removed. Flushing buffers is handled internally
by the driver.

-------------------------------------

ioctl IVTV_IOC_PASSTHROUGH is replaced by ioctl VIDEO_SELECT_SOURCE: use
VIDEO_SOURCE_MEMORY to turn the passthrough mode off, use VIDEO_SOURCE_DEMUX
to turn it on.

-------------------------------------

The following ioctls:

IVTV_IOC_START_DECODE
IVTV_IOC_STOP_DECODE
IVTV_IOC_G_SPEED
IVTV_IOC_S_SPEED
IVTV_IOC_DEC_STEP
IVTV_IOC_PAUSE_BLACK
IVTV_IOC_STOP
IVTV_IOC_PLAY
IVTV_IOC_PAUSE
IVTV_IOC_S_SLOW_FAST
IVTV_IOC_DEC_FAST_STOP

are replaced by the following ioctls:


VIDEO_STOP: stop decoding immediately and set the output to black.
VIDEO_PLAY: start decoding at normal speed.
VIDEO_FREEZE: pause decoding, keep the last frame.
VIDEO_CONTINUE: continue decoding.
VIDEO_COMMAND
VIDEO_TRY_COMMAND: these two ioctls work similar to the VIDIOC_[TRY_]ENCODER_COMMAND
ioctls.

The following commands exist:

VIDEO_CMD_PLAY: the play.speed value of the video_command struct selects the speed
as follows:
  0 or 1000 specifies normal speed,
  1 specifies forward single stepping,
 -1 specifies backward single stepping,
 >1: playback at speed/1000 of the normal speed,
<-1: reverse playback at (-speed/1000) of the normal speed. 

On return the play.format value tells you how to feed data to the decoder:

/* The decoder has no special format requirements */
#define VIDEO_PLAY_FMT_NONE         (0)
/* The decoder requires full GOPs */
#define VIDEO_PLAY_FMT_GOP          (1)

NOTE: if you change playback direction then at this moment you have to stop
the decoder first, then start again with the new speed setting. More research
is needed to determine if this can be avoided.


VIDEO_CMD_STOP: stop decoding. Two flags are available:

#define VIDEO_CMD_STOP_TO_BLACK      	(1 << 0)
#define VIDEO_CMD_STOP_IMMEDIATELY     	(1 << 1)

By default the decoder keeps the last frame and waits until all pending
buffers are decoded. 'STOP_IMMEDIATELY' will flush all queues and stop
at once.

You can also stop at the specified stop.pts value.


VIDEO_CMD_FREEZE: pause the decoder. One flag is available
with this command:

#define VIDEO_CMD_FREEZE_TO_BLACK     	(1 << 0)

By default the decoder keeps the last frame.


VIDEO_CMD_CONTINUE: continue decoding.

-------------------------------------

ioctls IVTV_IOC_G_PTS and IVTV_IOC_GET_TIMING are replaced by:

VIDEO_GET_FRAME_COUNT
VIDEO_GET_PTS

It is no longer possible to obtain the SCR timestamp.

-------------------------------------

ioctl IVTV_IOC_S_AUDMODE has been replaced with ioctls
AUDIO_CHANNEL_SELECT and AUDIO_BILINGUAL_CHANNEL_SELECT.

Possible channel selections are:

	AUDIO_STEREO,
	AUDIO_MONO_LEFT,
	AUDIO_MONO_RIGHT,
	AUDIO_MONO,
	AUDIO_STEREO_SWAPPED

AUDIO_CHANNEL_SELECT selects the audio output for a normal, one-language stream,
AUDIO_BILINGUAL_CHANNEL_SELECT selects the audio output for a bilingual stream.
The decoder automatically detects whether it is a bilingual stream or not and
uses the corresponding setting.

-------------------------------------

AUDIO_SET_MUTE is now used to select whether the audio is muted during 1.5 or 0.5
speed playback. By default the audio is not muted. During normal playback audio is
never muted and this ioctl has no effect on that.

-------------------------------------

ioctl IVTV_IOC_FRAMESYNC is replaced by VIDEO_GET_EVENT.

ivtv support two events: VIDEO_EVENT_DECODER_STOPPED and VIDEO_EVENT_VSYNC.
The first arrives when the decoder finishes decoding, the second arrives
at every Vsync (and so is very frequent).

If an event has arrived, then a select/poll that also waits for exceptions
will return and the exception bit is set. You have to call VIDEO_GET_EVENT
to discover which event arrived.

If you call VIDEO_GET_EVENT and there was no pending event, then this ioctl
will block until an event arrives (unless the file handle was set to non
blocking, in that case the ioctl will return immediately).

If the type was VIDEO_EVENT_VSYNC, then vsync_field will contain the
field identifier.

So IVTV_IOC_FRAMESYNC can be replaced by a call to VIDEO_GET_EVENT, possibly
followed by calls to VIDEO_GET_PTS and/or VIDEO_GET_FRAME_COUNT to get the
corresponding PTS/frame count.

Note that Vsync events are only recorded if 1) the application has called
poll/select or 2) if the application called VIDEO_GET_EVENT. So if you are
never interested in this event, then there is also no overhead.

Here is a copy of the relevant defines/struct from linux/dvb/video.h:

/* FIELD_UNKNOWN can be used if the hardware does not know whether
   the Vsync is for an odd, even or progressive (i.e. non-interlaced)
   field. */
#define VIDEO_VSYNC_FIELD_UNKNOWN  	(0)
#define VIDEO_VSYNC_FIELD_ODD 		(1)
#define VIDEO_VSYNC_FIELD_EVEN		(2)
#define VIDEO_VSYNC_FIELD_PROGRESSIVE	(3)

struct video_event {
	int32_t type;
#define VIDEO_EVENT_SIZE_CHANGED	1
#define VIDEO_EVENT_FRAME_RATE_CHANGED	2
#define VIDEO_EVENT_DECODER_STOPPED 	3
#define VIDEO_EVENT_VSYNC 		4
	time_t timestamp;
	union {
		video_size_t size;
		unsigned int frame_rate;	/* in frames per 1000sec */
		unsigned char vsync_field;	/* unknown/odd/even/progressive */
	} u;
};

-------------------------------

ioctl IVTV_IOC_GET_FB: this ioctl no longer exists, but the
best way to find the framebuffer that corresponds to the v4l2
video device is using the following code:

fd is the video output file descriptor:

	struct v4l2_framebuffer fbuf;
	int fbi;
	
	ioctl(fd, VIDIOC_G_FBUF, &fbuf);
	for (fbi = 0; fbi < 10; fbi++) {
		struct fb_fix_screeninfo si;
		char buf[10];

		sprintf(buf, "/dev/fb%d", fbi);
		ffb = open(buf, O_RDWR);
		if (ffb < 0) 
			continue;
		ioctl(ffb, FBIOGET_FSCREENINFO, &si);
		if (si.smem_start == (unsigned long)fbuf.base)
			break;
		close(ffb);
		ffb = -1;
	}
	if (ffb == -1) {
		fprintf(stderr, "Cannot find framebuffer\n");
		exit(1);
	}

So the smem_start from struct fb_fix_screeninfo should match the
base from struct v4l2_framebuffer. Both are pointers to the start
of the same framebuffer.

