By Date: <-- -->
By Thread: <-- -->

RFC: V4L2 MPEG Encoding API: Part 1 (second version)



This is part 1 of the proposal for adding an MPEG API to V4L2. This part 
describes the changes and new ioctls needed. Part 2 will describe the 
actual MPEG controls.

This is the revised version. The main changes against the first are:

- the whole pointer control stuff has been removed, but space has been 
reserved for such a feature as it is almost certainly needed in the 
future.
- an extra UPDATE flag has been added.
- an error_idx field has been added to return the index of the first 
control that had an error.

If there are no serious objections, then I'll start implementing this.

Background
==========

V4L2 already contains an experimental API through the 
VIDIOC_G/S_MPEGCOMP ioctls. These ioctls use the struct 
v4l2_mpeg_compression to set the various compression parameters. 
However, there are NO applications that use this API. Instead, the 
de-facto standard is the API from the as-yet out-of-tree ivtv driver. 
It is similar to the kernel experimental API but using 
IVTV_IOC_G/S_CODEC ioctls and a struct ivtv_ioctl_codec.

This is obviously not a satisfactory situation and this proposal tries 
to make a well-defined yet extensible API that replaces both the kernel 
and the ivtv APIs.

This proposal is based on earlier email discussions.

Requirements
============

1) fully support the features of the currently known MPEG encoder 
devices.
2) be extensible to support future MPEG encoder (or more general 
video/audio compression) devices.
3) support the device-specific features, but in such a way that 
applications can still discover those features in a well-defined 
manner.

Given the complexity of the currently known MPEG encoder devices the 
classical solution along the lines of VIDIOC_G/S_MPEGCOMP fail. Trying 
to put all the possible parameters into one structure results in a 
ridiculously large and unwieldy struct.

After much discussion the decision was made to base the API on the 
control mechanism instead. Controls have the advantage that they are 
easily extendible and that the properties of the control can be queried 
and presented to the user in a GUI.

However, controls used for compression devices are different from the
traditional user controls in that they are not necessarily independent 
from one another, that often you need to set multiple controls at one 
go ('atomicity'), and that controls can depend on other controls.

A mechanism to pass variable-sized data with a control is also 
desirable.

Proposed solution
=================

A new extended control struct is created:

struct v4l2_ext_control
{
        __u32 id;
        __u32 reserved2[2];
	union {
        	__s32 value;
		void *reserved;
	}
};

Where v4l2_control is used for user controls, this struct is for 
controls that are used to set MPEG encoder parameters. The user 
controls should not be mixed with the extended controls.

It is very likely that in the future controls containing more complex 
data are needed. For example, controls that set a quantization matrix. 
At the moment, no such controls are defined. But to allow such behavior 
in the future space is reserved for a 'size' field and a data pointer 
field.

The precise mechanism to determine what the data type for such a pointer
control is is still to be determined, but having a new v4l2_ctrl_type 
for each type of complex data control is the most likely candidate. 
Alternatively, pointer types can be added to the v4l2_ctrl_type enum.

Note that such new types can only appear with extended controls, not 
with user controls.

Three new flags for the v4l2_queryctrl struct are also defined:

V4L2_CTRL_FLAG_READ_ONLY

If set, then this control cannot be written.

V4L2_CTRL_FLAG_UPDATE

If set, then changing this control will require a GUI application to
check the value of the other MPEG controls, since other MPEG controls
depend on this one.

V4L2_CTRL_FLAG_INACTIVE   

If set, then this control is inactive. The DISABLED flag is used when a 
control is not supported by the device. The INACTIVE flag is used when 
a control is to be hidden or disabled due to the setting of another 
control. For example, if the bitrate is constant, then the bitrate PEAK 
control becomes inactive, since it has no meaning unless the bitrate is 
variable. You can still set an inactive control. The new value will be 
used when the control becomes active again. So this flag is purely an 
application hint.

As said earlier, extended controls can depend on one another. These 
dependencies MUST be documented in the V4L2 API spec.

A note on the QUERYMENU ioctl: the application must be aware that not 
all menu items may be available depending on the device. So when the 
application iterates through the minimum to maximum menu items, some 
may return -EINVAL if they are not supported.

The controls are set using a set of three new ioctls:

VIDIOC_G_EXT_CTRLS, VIDIOC_S_EXT_CTRLS, VIDIOC_TRY_EXT_CTRLS

They receive this struct:

struct v4l2_ext_controls
{
	__u32 count;
	__u32 error_idx;
	__u32 reserved[2];
	struct v4l2_ext_control *controls;
};

where 'controls' points to an array of 'count' v4l2_ext_control 
structures. The reserved values must be set to 0. The error_idx will be 
filled with the index (0-based) of the first control containing an 
error. If the ioctl returns 0 (no error), then the error_idx value 
should be ignored.

If any control in the control list contains an error, then no change 
will have been made. So the controls are only set if all controls are 
valid (atomicity).

VIDIOC_QUERYCTRL and VIDIOC_QUERYMENU work the same for extended 
controls as for user controls. No changes there.

The old VIDIOC_G/S_MPEGCOMP ioctls and the v4l2_mpeg_compression struct 
are deleted altogether.

The compression extended controls start at this base ID:

#define V4L2_CID_COMP_BASE 0x00010000
#define V4L2_CID_COMP_DRIVER_BASE (V4L2_CID_COMP_BASE+0)
#define V4L2_CID_COMP_LASTP1 (V4L2_CID_COMP_BASE+1) /* Last CID + 1 */

The special read-only V4L2_CID_COMP_DRIVER_BASE control returns the 
control ID at which the driver-specific controls begin. Driver specific 
controls are for example used to set encoder filters. Such filters are 
driver (chipset) specific and cannot be generalized. But they can be 
very useful to have.

This way the application can obtain the start of the driver-specific  
controls and either make a custom dialog for that driver or just 
enumerate the controls and create a dialog based on the 
VIDIOC_QUERYCTRL and VIDIOC_QUERYMENU results.
 
All compression drivers must support this control. If there are no 
driver-specific controls, then this control must return 0.

Of course, the extended control mechanism allows other similarly 
complicated APIs to add their own ID ranges in the future. However, for 
now the API is limited to devices supporting the V4L2_PIX_FMT_MPEG 
format, that is MPEG-1/2/4 type compression streams.

--
video4linux-list mailing list
Unsubscribe mailto:video4linux-list-request (at) redhat.com?subject=unsubscribe
https://www.redhat.com/mailman/listinfo/video4linux-list