forked from marfrit/libva-v4l2-request-fourier
Rework comments by splitting them into README and removing redundant ones
Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
This commit is contained in:
@@ -25,3 +25,46 @@ Sample media files can be obtained from:
|
|||||||
|
|
||||||
http://samplemedia.linaro.org/MPEG2/
|
http://samplemedia.linaro.org/MPEG2/
|
||||||
http://samplemedia.linaro.org/MPEG4/SVT/
|
http://samplemedia.linaro.org/MPEG4/SVT/
|
||||||
|
|
||||||
|
## Technical Notes
|
||||||
|
|
||||||
|
### Surface
|
||||||
|
|
||||||
|
A Surface is an internal data structure never handled by the VA's user
|
||||||
|
containing the output of a rendering. Usualy, a bunch of surfaces are created
|
||||||
|
at the begining of decoding and they are then used alternatively. When
|
||||||
|
created, a surface is assigned a corresponding v4l capture buffer and it is
|
||||||
|
kept until the end of decoding. Syncing a surface waits for the v4l buffer to
|
||||||
|
be available and then dequeue it.
|
||||||
|
|
||||||
|
Note: since a Surface is kept private from the VA's user, it can ask to
|
||||||
|
directly render a Surface on screen in an X Drawable. Some kind of
|
||||||
|
implementation is available in PutSurface but this is only for development
|
||||||
|
purpose.
|
||||||
|
|
||||||
|
### Context
|
||||||
|
|
||||||
|
A Context is a global data structure used for rendering a video of a certain
|
||||||
|
format. When a context is created, input buffers are created and v4l's output
|
||||||
|
(which is the compressed data input queue, since capture is the real output)
|
||||||
|
format is set.
|
||||||
|
|
||||||
|
### Picture
|
||||||
|
|
||||||
|
A Picture is an encoded input frame made of several buffers. A single input
|
||||||
|
can contain slice data, headers and IQ matrix. Each Picture is assigned a
|
||||||
|
request ID when created and each corresponding buffer might be turned into a
|
||||||
|
v4l buffers or extended control when rendered. Finally they are submitted to
|
||||||
|
kernel space when reaching EndPicture.
|
||||||
|
|
||||||
|
The real rendering is done in EndPicture instead of RenderPicture
|
||||||
|
because the v4l2 driver expects to have the full corresponding
|
||||||
|
extended control when a buffer is queued and we don't know in which
|
||||||
|
order the different RenderPicture will be called.
|
||||||
|
|
||||||
|
### Image
|
||||||
|
|
||||||
|
An Image is a standard data structure containing rendered frames in a usable
|
||||||
|
pixel format. Here we only use NV12 buffers which are converted from sunxi's
|
||||||
|
proprietary tiled pixel format with tiled_yuv when deriving an Image from a
|
||||||
|
Surface.
|
||||||
|
|||||||
+6
-7
@@ -36,12 +36,6 @@
|
|||||||
|
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* A Buffer is a memory zone used to handle all kind of data, for example an IQ
|
|
||||||
* matrix or image buffer (which are allocated using realloc) or slice data
|
|
||||||
* (which are mmapped from v4l's kernel space)
|
|
||||||
*/
|
|
||||||
|
|
||||||
VAStatus SunxiCedrusCreateBuffer(VADriverContextP context,
|
VAStatus SunxiCedrusCreateBuffer(VADriverContextP context,
|
||||||
VAContextID context_id, VABufferType type, unsigned int size,
|
VAContextID context_id, VABufferType type, unsigned int size,
|
||||||
unsigned int count, void *data, VABufferID *buffer_id)
|
unsigned int count, void *data, VABufferID *buffer_id)
|
||||||
@@ -54,6 +48,12 @@ VAStatus SunxiCedrusCreateBuffer(VADriverContextP context,
|
|||||||
|
|
||||||
memset(plane, 0, sizeof(struct v4l2_plane));
|
memset(plane, 0, sizeof(struct v4l2_plane));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A Buffer is a memory zone used to handle all kind of data, for example an IQ
|
||||||
|
* matrix or image buffer (which are allocated using realloc) or slice data
|
||||||
|
* (which are mmapped from v4l's kernel space)
|
||||||
|
*/
|
||||||
|
|
||||||
/* Validate type */
|
/* Validate type */
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case VAPictureParameterBufferType:
|
case VAPictureParameterBufferType:
|
||||||
@@ -202,7 +202,6 @@ VAStatus SunxiCedrusDestroyBuffer(VADriverContextP context,
|
|||||||
return VA_STATUS_SUCCESS;
|
return VA_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sunxi-cedrus doesn't support buffer info */
|
|
||||||
VAStatus SunxiCedrusBufferInfo(VADriverContextP context, VABufferID buffer_id,
|
VAStatus SunxiCedrusBufferInfo(VADriverContextP context, VABufferID buffer_id,
|
||||||
VABufferType *type, unsigned int *size, unsigned int *count)
|
VABufferType *type, unsigned int *size, unsigned int *count)
|
||||||
{ return VA_STATUS_ERROR_UNIMPLEMENTED; }
|
{ return VA_STATUS_ERROR_UNIMPLEMENTED; }
|
||||||
|
|||||||
+1
-1
@@ -63,4 +63,4 @@ VAStatus SunxiCedrusDestroyBuffer(VADriverContextP context,
|
|||||||
VAStatus SunxiCedrusBufferInfo(VADriverContextP context, VABufferID buffer_id,
|
VAStatus SunxiCedrusBufferInfo(VADriverContextP context, VABufferID buffer_id,
|
||||||
VABufferType *type, unsigned int *size, unsigned int *count);
|
VABufferType *type, unsigned int *size, unsigned int *count);
|
||||||
|
|
||||||
#endif /* _BUFFER_H_ */
|
#endif
|
||||||
|
|||||||
@@ -37,13 +37,6 @@
|
|||||||
|
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* A Context is a global data structure used for rendering a video of a certain
|
|
||||||
* format. When a context is created, input buffers are created and v4l's output
|
|
||||||
* (which is the compressed data input queue, since capture is the real output)
|
|
||||||
* format is set.
|
|
||||||
*/
|
|
||||||
|
|
||||||
VAStatus SunxiCedrusCreateContext(VADriverContextP context,
|
VAStatus SunxiCedrusCreateContext(VADriverContextP context,
|
||||||
VAConfigID config_id, int picture_width, int picture_height, int flag,
|
VAConfigID config_id, int picture_width, int picture_height, int flag,
|
||||||
VASurfaceID *surfaces_ids, int surfaces_count,
|
VASurfaceID *surfaces_ids, int surfaces_count,
|
||||||
|
|||||||
+1
-4
@@ -30,9 +30,6 @@
|
|||||||
|
|
||||||
#include "object_heap.h"
|
#include "object_heap.h"
|
||||||
|
|
||||||
/* We can't dynamically call VIDIOC_REQBUFS for every MPEG slice we create.
|
|
||||||
* Indeed, the queue might be busy processing a previous buffer, so we need to
|
|
||||||
* pre-allocate a set of buffers with a max size */
|
|
||||||
#define INPUT_BUFFER_MAX_SIZE 131072
|
#define INPUT_BUFFER_MAX_SIZE 131072
|
||||||
#define INPUT_BUFFERS_NB 6
|
#define INPUT_BUFFERS_NB 6
|
||||||
|
|
||||||
@@ -62,4 +59,4 @@ VAStatus SunxiCedrusCreateContext(VADriverContextP context,
|
|||||||
VAStatus SunxiCedrusDestroyContext(VADriverContextP context,
|
VAStatus SunxiCedrusDestroyContext(VADriverContextP context,
|
||||||
VAContextID context_id);
|
VAContextID context_id);
|
||||||
|
|
||||||
#endif /* _CONTEXT_H_ */
|
#endif
|
||||||
|
|||||||
@@ -32,13 +32,6 @@
|
|||||||
|
|
||||||
#include "tiled_yuv.h"
|
#include "tiled_yuv.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* An Image is a standard data structure containing rendered frames in a usable
|
|
||||||
* pixel format. Here we only use NV12 buffers which are converted from sunxi's
|
|
||||||
* proprietary tiled pixel format with tiled_yuv when deriving an Image from a
|
|
||||||
* Surface.
|
|
||||||
*/
|
|
||||||
|
|
||||||
VAStatus SunxiCedrusQueryImageFormats(VADriverContextP context,
|
VAStatus SunxiCedrusQueryImageFormats(VADriverContextP context,
|
||||||
VAImageFormat *formats, int *formats_count)
|
VAImageFormat *formats, int *formats_count)
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -55,4 +55,4 @@ VAStatus SunxiCedrusPutImage(VADriverContextP context, VASurfaceID surface_id,
|
|||||||
unsigned int src_height, int dst_x, int dst_y, unsigned int dst_width,
|
unsigned int src_height, int dst_x, int dst_y, unsigned int dst_width,
|
||||||
unsigned int dst_height);
|
unsigned int dst_height);
|
||||||
|
|
||||||
#endif /* _IMAGE_H_ */
|
#endif
|
||||||
|
|||||||
@@ -34,11 +34,6 @@
|
|||||||
|
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* This file takes care of filling v4l2's frame API MPEG2 headers extended
|
|
||||||
* controls from VA's data structures.
|
|
||||||
*/
|
|
||||||
|
|
||||||
VAStatus sunxi_cedrus_render_mpeg2_slice_data(VADriverContextP ctx,
|
VAStatus sunxi_cedrus_render_mpeg2_slice_data(VADriverContextP ctx,
|
||||||
struct object_context *obj_context, struct object_surface *obj_surface,
|
struct object_context *obj_context, struct object_surface *obj_surface,
|
||||||
struct object_buffer *obj_buffer)
|
struct object_buffer *obj_buffer)
|
||||||
|
|||||||
+1
-1
@@ -41,4 +41,4 @@ VAStatus sunxi_cedrus_render_mpeg2_picture_parameter(VADriverContextP ctx,
|
|||||||
struct object_context *obj_context, struct object_surface *obj_surface,
|
struct object_context *obj_context, struct object_surface *obj_surface,
|
||||||
struct object_buffer *obj_buffer);
|
struct object_buffer *obj_buffer);
|
||||||
|
|
||||||
#endif /* _MPEG2_H_ */
|
#endif
|
||||||
|
|||||||
+1
-1
@@ -90,4 +90,4 @@ void object_heap_free(object_heap_p heap, object_base_p obj);
|
|||||||
*/
|
*/
|
||||||
void object_heap_destroy(object_heap_p heap);
|
void object_heap_destroy(object_heap_p heap);
|
||||||
|
|
||||||
#endif /* OBJECT_HEAP_H */
|
#endif
|
||||||
|
|||||||
@@ -41,14 +41,6 @@
|
|||||||
|
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* A Picture is an encoded input frame made of several buffers. A single input
|
|
||||||
* can contain slice data, headers and IQ matrix. Each Picture is assigned a
|
|
||||||
* request ID when created and each corresponding buffer might be turned into a
|
|
||||||
* v4l buffers or extended control when rendered. Finally they are submitted to
|
|
||||||
* kernel space when reaching EndPicture.
|
|
||||||
*/
|
|
||||||
|
|
||||||
VAStatus SunxiCedrusBeginPicture(VADriverContextP context,
|
VAStatus SunxiCedrusBeginPicture(VADriverContextP context,
|
||||||
VAContextID context_id, VASurfaceID surface_id)
|
VAContextID context_id, VASurfaceID surface_id)
|
||||||
{
|
{
|
||||||
@@ -162,12 +154,6 @@ VAStatus SunxiCedrusEndPicture(VADriverContextP context,
|
|||||||
return vaStatus;
|
return vaStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The real rendering is done in EndPicture instead of RenderPicture
|
|
||||||
* because the v4l2 driver expects to have the full corresponding
|
|
||||||
* extended control when a buffer is queued and we don't know in which
|
|
||||||
* order the different RenderPicture will be called.
|
|
||||||
*/
|
|
||||||
request_fd = driver_data->request_fds[obj_surface->input_buf_index];
|
request_fd = driver_data->request_fds[obj_surface->input_buf_index];
|
||||||
if(request_fd < 0) {
|
if(request_fd < 0) {
|
||||||
assert(ioctl(driver_data->mem2mem_fd, VIDIOC_NEW_REQUEST, &media_request)==0);
|
assert(ioctl(driver_data->mem2mem_fd, VIDIOC_NEW_REQUEST, &media_request)==0);
|
||||||
|
|||||||
+1
-1
@@ -37,4 +37,4 @@ VAStatus SunxiCedrusRenderPicture(VADriverContextP context,
|
|||||||
VAStatus SunxiCedrusEndPicture(VADriverContextP context,
|
VAStatus SunxiCedrusEndPicture(VADriverContextP context,
|
||||||
VAContextID context_id);
|
VAContextID context_id);
|
||||||
|
|
||||||
#endif /* _PICTURE_H_ */
|
#endif
|
||||||
|
|||||||
@@ -26,10 +26,6 @@
|
|||||||
#include "sunxi_cedrus.h"
|
#include "sunxi_cedrus.h"
|
||||||
#include "subpicture.h"
|
#include "subpicture.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* Subpictures aren't supported yet
|
|
||||||
*/
|
|
||||||
|
|
||||||
VAStatus SunxiCedrusQuerySubpictureFormats(VADriverContextP context,
|
VAStatus SunxiCedrusQuerySubpictureFormats(VADriverContextP context,
|
||||||
VAImageFormat *formats, unsigned int *flags,
|
VAImageFormat *formats, unsigned int *flags,
|
||||||
unsigned int *formats_count)
|
unsigned int *formats_count)
|
||||||
|
|||||||
+1
-1
@@ -54,4 +54,4 @@ VAStatus SunxiCedrusDeassociateSubpicture(VADriverContextP context,
|
|||||||
VASubpictureID subpicture_id, VASurfaceID *surfaces_ids,
|
VASubpictureID subpicture_id, VASurfaceID *surfaces_ids,
|
||||||
int surfaces_count);
|
int surfaces_count);
|
||||||
|
|
||||||
#endif /* _SUBPICTURE_H_ */
|
#endif
|
||||||
|
|||||||
+5
-9
@@ -49,18 +49,17 @@
|
|||||||
|
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
|
|
||||||
/* We need to use stderr if we want to be heard */
|
|
||||||
void sunxi_cedrus_msg(const char *msg, ...)
|
void sunxi_cedrus_msg(const char *msg, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
|
/* We need to use stderr if we want to be heard */
|
||||||
fprintf(stderr, "sunxi_cedrus_drv_video: ");
|
fprintf(stderr, "sunxi_cedrus_drv_video: ");
|
||||||
va_start(args, msg);
|
va_start(args, msg);
|
||||||
vfprintf(stderr, msg, args);
|
vfprintf(stderr, msg, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free memory and close v4l device */
|
|
||||||
VAStatus SunxiCedrusTerminate(VADriverContextP context)
|
VAStatus SunxiCedrusTerminate(VADriverContextP context)
|
||||||
{
|
{
|
||||||
struct sunxi_cedrus_driver_data *driver_data =
|
struct sunxi_cedrus_driver_data *driver_data =
|
||||||
@@ -69,6 +68,8 @@ VAStatus SunxiCedrusTerminate(VADriverContextP context)
|
|||||||
struct object_config *obj_config;
|
struct object_config *obj_config;
|
||||||
object_heap_iterator iter;
|
object_heap_iterator iter;
|
||||||
|
|
||||||
|
/* Free memory and close v4l device */
|
||||||
|
|
||||||
for (int i = 0; i < INPUT_BUFFERS_NB; i++)
|
for (int i = 0; i < INPUT_BUFFERS_NB; i++)
|
||||||
if (driver_data->request_fds[i] >= 0)
|
if (driver_data->request_fds[i] >= 0)
|
||||||
close(driver_data->request_fds[i]);
|
close(driver_data->request_fds[i]);
|
||||||
@@ -103,12 +104,8 @@ VAStatus SunxiCedrusTerminate(VADriverContextP context)
|
|||||||
return VA_STATUS_SUCCESS;
|
return VA_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only expose the init function */
|
/* Only expose the init function. */
|
||||||
VAStatus __attribute__((visibility("default")))
|
VAStatus __attribute__((visibility("default"))) VA_DRIVER_INIT_FUNC(VADriverContextP context)
|
||||||
VA_DRIVER_INIT_FUNC(VADriverContextP context);
|
|
||||||
|
|
||||||
/* Setup a bunch of function pointers for VA */
|
|
||||||
VAStatus VA_DRIVER_INIT_FUNC(VADriverContextP context)
|
|
||||||
{
|
{
|
||||||
struct VADriverVTable * const vtable = context->vtable;
|
struct VADriverVTable * const vtable = context->vtable;
|
||||||
struct sunxi_cedrus_driver_data *driver_data;
|
struct sunxi_cedrus_driver_data *driver_data;
|
||||||
@@ -206,4 +203,3 @@ VAStatus VA_DRIVER_INIT_FUNC(VADriverContextP context)
|
|||||||
|
|
||||||
return VA_STATUS_SUCCESS;
|
return VA_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -57,4 +57,4 @@ struct sunxi_cedrus_driver_data {
|
|||||||
int slice_offset[INPUT_BUFFERS_NB];
|
int slice_offset[INPUT_BUFFERS_NB];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _SUNXI_CEDRUS_H_ */
|
#endif
|
||||||
|
|||||||
+3
-15
@@ -38,20 +38,6 @@
|
|||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* A Surface is an internal data structure never handled by the VA's user
|
|
||||||
* containing the output of a rendering. Usualy, a bunch of surfaces are created
|
|
||||||
* at the begining of decoding and they are then used alternatively. When
|
|
||||||
* created, a surface is assigned a corresponding v4l capture buffer and it is
|
|
||||||
* kept until the end of decoding. Syncing a surface waits for the v4l buffer to
|
|
||||||
* be available and then dequeue it.
|
|
||||||
*
|
|
||||||
* Note: since a Surface is kept private from the VA's user, it can ask to
|
|
||||||
* directly render a Surface on screen in an X Drawable. Some kind of
|
|
||||||
* implementation is available in PutSurface but this is only for development
|
|
||||||
* purpose.
|
|
||||||
*/
|
|
||||||
|
|
||||||
VAStatus SunxiCedrusCreateSurfaces(VADriverContextP context, int width,
|
VAStatus SunxiCedrusCreateSurfaces(VADriverContextP context, int width,
|
||||||
int height, int format, int surfaces_count, VASurfaceID *surfaces)
|
int height, int format, int surfaces_count, VASurfaceID *surfaces)
|
||||||
{
|
{
|
||||||
@@ -241,7 +227,7 @@ VAStatus SunxiCedrusQuerySurfaceStatus(VADriverContextP context,
|
|||||||
return vaStatus;
|
return vaStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WARNING: This is for development purpose only!!! */
|
|
||||||
VAStatus SunxiCedrusPutSurface(VADriverContextP context, VASurfaceID surface_id,
|
VAStatus SunxiCedrusPutSurface(VADriverContextP context, VASurfaceID surface_id,
|
||||||
void *draw, short src_x, short src_y, unsigned short src_width,
|
void *draw, short src_x, short src_y, unsigned short src_width,
|
||||||
unsigned short src_height, short dst_x, short dst_y,
|
unsigned short src_height, short dst_x, short dst_y,
|
||||||
@@ -261,6 +247,8 @@ VAStatus SunxiCedrusPutSurface(VADriverContextP context, VASurfaceID surface_id,
|
|||||||
int x, y;
|
int x, y;
|
||||||
struct object_surface *obj_surface;
|
struct object_surface *obj_surface;
|
||||||
|
|
||||||
|
/* WARNING: This is for development purpose only!!! */
|
||||||
|
|
||||||
obj_surface = SURFACE(surface);
|
obj_surface = SURFACE(surface);
|
||||||
assert(obj_surface);
|
assert(obj_surface);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -69,4 +69,4 @@ VAStatus SunxiCedrusLockSurface(VADriverContextP context,
|
|||||||
VAStatus SunxiCedrusUnlockSurface(VADriverContextP context,
|
VAStatus SunxiCedrusUnlockSurface(VADriverContextP context,
|
||||||
VASurfaceID surface_id);
|
VASurfaceID surface_id);
|
||||||
|
|
||||||
#endif /* _SURFACES_H_ */
|
#endif
|
||||||
|
|||||||
@@ -33,12 +33,6 @@
|
|||||||
|
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* This file provides generalities to VA's user regarding the file formats
|
|
||||||
* supported by the v4l driver. It uses VIDIOC_ENUM_FMT to make the
|
|
||||||
* correspondence between v4l and VA video formats.
|
|
||||||
*/
|
|
||||||
|
|
||||||
VAStatus SunxiCedrusQueryConfigProfiles(VADriverContextP context,
|
VAStatus SunxiCedrusQueryConfigProfiles(VADriverContextP context,
|
||||||
VAProfile *profiles, int *profiles_count)
|
VAProfile *profiles, int *profiles_count)
|
||||||
{
|
{
|
||||||
@@ -237,7 +231,6 @@ VAStatus SunxiCedrusQueryConfigAttributes(VADriverContextP context,
|
|||||||
return vaStatus;
|
return vaStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sunxi-cedrus doesn't support display attributes */
|
|
||||||
VAStatus SunxiCedrusQueryDisplayAttributes(VADriverContextP context,
|
VAStatus SunxiCedrusQueryDisplayAttributes(VADriverContextP context,
|
||||||
VADisplayAttribute *attributes, int *attributes_count)
|
VADisplayAttribute *attributes, int *attributes_count)
|
||||||
{ return VA_STATUS_ERROR_UNKNOWN; }
|
{ return VA_STATUS_ERROR_UNKNOWN; }
|
||||||
|
|||||||
+1
-1
@@ -64,4 +64,4 @@ VAStatus SunxiCedrusGetDisplayAttributes(VADriverContextP context,
|
|||||||
VAStatus SunxiCedrusSetDisplayAttributes(VADriverContextP context,
|
VAStatus SunxiCedrusSetDisplayAttributes(VADriverContextP context,
|
||||||
VADisplayAttribute *attributes, int *attributes_count);
|
VADisplayAttribute *attributes, int *attributes_count);
|
||||||
|
|
||||||
#endif /* _CONFIG_H_ */
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user