Add support for the single-planar V4L2 API
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
This commit is contained in:
+9
-2
@@ -197,9 +197,17 @@ VAStatus RequestAcquireBufferHandle(VADriverContextP context,
|
|||||||
struct request_data *driver_data = context->pDriverData;
|
struct request_data *driver_data = context->pDriverData;
|
||||||
struct object_buffer *buffer_object;
|
struct object_buffer *buffer_object;
|
||||||
struct object_surface *surface_object;
|
struct object_surface *surface_object;
|
||||||
|
struct video_format *video_format;
|
||||||
|
unsigned int capture_type;
|
||||||
int export_fd;
|
int export_fd;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
video_format = driver_data->video_format;
|
||||||
|
if (video_format == NULL)
|
||||||
|
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
|
capture_type = v4l2_type_video_capture(video_format->v4l2_mplane);
|
||||||
|
|
||||||
if (buffer_info->mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME ||
|
if (buffer_info->mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME ||
|
||||||
!video_format_is_linear(driver_data->video_format))
|
!video_format_is_linear(driver_data->video_format))
|
||||||
return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
|
return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
|
||||||
@@ -218,8 +226,7 @@ VAStatus RequestAcquireBufferHandle(VADriverContextP context,
|
|||||||
if (surface_object->destination_buffers_count > 1)
|
if (surface_object->destination_buffers_count > 1)
|
||||||
return VA_STATUS_ERROR_OPERATION_FAILED;
|
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
rc = v4l2_export_buffer(driver_data->video_fd,
|
rc = v4l2_export_buffer(driver_data->video_fd, capture_type,
|
||||||
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
|
|
||||||
surface_object->destination_index, O_RDONLY,
|
surface_object->destination_index, O_RDONLY,
|
||||||
&export_fd, 1);
|
&export_fd, 1);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
|
|||||||
+3
-3
@@ -112,7 +112,7 @@ VAStatus RequestQueryConfigProfiles(VADriverContextP context,
|
|||||||
bool found;
|
bool found;
|
||||||
|
|
||||||
found = v4l2_find_format(driver_data->video_fd,
|
found = v4l2_find_format(driver_data->video_fd,
|
||||||
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
|
V4L2_BUF_TYPE_VIDEO_OUTPUT,
|
||||||
V4L2_PIX_FMT_MPEG2_SLICE);
|
V4L2_PIX_FMT_MPEG2_SLICE);
|
||||||
if (found && index < (V4L2_REQUEST_MAX_CONFIG_ATTRIBUTES - 2)) {
|
if (found && index < (V4L2_REQUEST_MAX_CONFIG_ATTRIBUTES - 2)) {
|
||||||
profiles[index++] = VAProfileMPEG2Simple;
|
profiles[index++] = VAProfileMPEG2Simple;
|
||||||
@@ -120,7 +120,7 @@ VAStatus RequestQueryConfigProfiles(VADriverContextP context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
found = v4l2_find_format(driver_data->video_fd,
|
found = v4l2_find_format(driver_data->video_fd,
|
||||||
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
|
V4L2_BUF_TYPE_VIDEO_OUTPUT,
|
||||||
V4L2_PIX_FMT_H264_SLICE);
|
V4L2_PIX_FMT_H264_SLICE);
|
||||||
if (found && index < (V4L2_REQUEST_MAX_CONFIG_ATTRIBUTES - 5)) {
|
if (found && index < (V4L2_REQUEST_MAX_CONFIG_ATTRIBUTES - 5)) {
|
||||||
profiles[index++] = VAProfileH264Main;
|
profiles[index++] = VAProfileH264Main;
|
||||||
@@ -131,7 +131,7 @@ VAStatus RequestQueryConfigProfiles(VADriverContextP context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
found = v4l2_find_format(driver_data->video_fd,
|
found = v4l2_find_format(driver_data->video_fd,
|
||||||
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
|
V4L2_BUF_TYPE_VIDEO_OUTPUT,
|
||||||
V4L2_PIX_FMT_HEVC_SLICE);
|
V4L2_PIX_FMT_HEVC_SLICE);
|
||||||
if (found && index < (V4L2_REQUEST_MAX_CONFIG_ATTRIBUTES - 1))
|
if (found && index < (V4L2_REQUEST_MAX_CONFIG_ATTRIBUTES - 1))
|
||||||
profiles[index++] = VAProfileHEVCMain;
|
profiles[index++] = VAProfileHEVCMain;
|
||||||
|
|||||||
+28
-19
@@ -50,18 +50,27 @@ VAStatus RequestCreateContext(VADriverContextP context, VAConfigID config_id,
|
|||||||
struct object_config *config_object;
|
struct object_config *config_object;
|
||||||
struct object_surface *surface_object;
|
struct object_surface *surface_object;
|
||||||
struct object_context *context_object = NULL;
|
struct object_context *context_object = NULL;
|
||||||
|
struct video_format *video_format;
|
||||||
unsigned int length;
|
unsigned int length;
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
void *source_data = MAP_FAILED;
|
void *source_data = MAP_FAILED;
|
||||||
VASurfaceID *ids = NULL;
|
VASurfaceID *ids = NULL;
|
||||||
VAContextID id;
|
VAContextID id;
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
|
unsigned int output_type, capture_type;
|
||||||
unsigned int pixelformat;
|
unsigned int pixelformat;
|
||||||
unsigned int index_base;
|
unsigned int index_base;
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
video_format = driver_data->video_format;
|
||||||
|
if (video_format == NULL)
|
||||||
|
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
|
output_type = v4l2_type_video_output(video_format->v4l2_mplane);
|
||||||
|
capture_type = v4l2_type_video_capture(video_format->v4l2_mplane);
|
||||||
|
|
||||||
config_object = CONFIG(driver_data, config_id);
|
config_object = CONFIG(driver_data, config_id);
|
||||||
if (config_object == NULL) {
|
if (config_object == NULL) {
|
||||||
status = VA_STATUS_ERROR_INVALID_CONFIG;
|
status = VA_STATUS_ERROR_INVALID_CONFIG;
|
||||||
@@ -99,16 +108,14 @@ VAStatus RequestCreateContext(VADriverContextP context, VAConfigID config_id,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = v4l2_set_format(driver_data->video_fd,
|
rc = v4l2_set_format(driver_data->video_fd, output_type, pixelformat,
|
||||||
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, pixelformat,
|
|
||||||
picture_width, picture_height);
|
picture_width, picture_height);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
status = VA_STATUS_ERROR_OPERATION_FAILED;
|
status = VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = v4l2_create_buffers(driver_data->video_fd,
|
rc = v4l2_create_buffers(driver_data->video_fd, output_type,
|
||||||
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
|
|
||||||
surfaces_count, &index_base);
|
surfaces_count, &index_base);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
status = VA_STATUS_ERROR_ALLOCATION_FAILED;
|
status = VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
@@ -137,9 +144,8 @@ VAStatus RequestCreateContext(VADriverContextP context, VAConfigID config_id,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = v4l2_query_buffer(driver_data->video_fd,
|
rc = v4l2_query_buffer(driver_data->video_fd, output_type,
|
||||||
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, index,
|
index, &length, &offset, 1);
|
||||||
&length, &offset, 1);
|
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
status = VA_STATUS_ERROR_ALLOCATION_FAILED;
|
status = VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
goto error;
|
goto error;
|
||||||
@@ -157,15 +163,13 @@ VAStatus RequestCreateContext(VADriverContextP context, VAConfigID config_id,
|
|||||||
surface_object->source_size = length;
|
surface_object->source_size = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = v4l2_set_stream(driver_data->video_fd,
|
rc = v4l2_set_stream(driver_data->video_fd, output_type, true);
|
||||||
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, true);
|
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
status = VA_STATUS_ERROR_OPERATION_FAILED;
|
status = VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = v4l2_set_stream(driver_data->video_fd,
|
rc = v4l2_set_stream(driver_data->video_fd, capture_type, true);
|
||||||
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, true);
|
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
status = VA_STATUS_ERROR_OPERATION_FAILED;
|
status = VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
goto error;
|
goto error;
|
||||||
@@ -203,20 +207,27 @@ VAStatus RequestDestroyContext(VADriverContextP context, VAContextID context_id)
|
|||||||
{
|
{
|
||||||
struct request_data *driver_data = context->pDriverData;
|
struct request_data *driver_data = context->pDriverData;
|
||||||
struct object_context *context_object;
|
struct object_context *context_object;
|
||||||
|
struct video_format *video_format;
|
||||||
|
unsigned int output_type, capture_type;
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
video_format = driver_data->video_format;
|
||||||
|
if (video_format == NULL)
|
||||||
|
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
|
output_type = v4l2_type_video_output(video_format->v4l2_mplane);
|
||||||
|
capture_type = v4l2_type_video_capture(video_format->v4l2_mplane);
|
||||||
|
|
||||||
context_object = CONTEXT(driver_data, context_id);
|
context_object = CONTEXT(driver_data, context_id);
|
||||||
if (context_object == NULL)
|
if (context_object == NULL)
|
||||||
return VA_STATUS_ERROR_INVALID_CONTEXT;
|
return VA_STATUS_ERROR_INVALID_CONTEXT;
|
||||||
|
|
||||||
rc = v4l2_set_stream(driver_data->video_fd,
|
rc = v4l2_set_stream(driver_data->video_fd, output_type, false);
|
||||||
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, false);
|
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return VA_STATUS_ERROR_OPERATION_FAILED;
|
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
rc = v4l2_set_stream(driver_data->video_fd,
|
rc = v4l2_set_stream(driver_data->video_fd, capture_type, false);
|
||||||
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, false);
|
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return VA_STATUS_ERROR_OPERATION_FAILED;
|
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
@@ -232,13 +243,11 @@ VAStatus RequestDestroyContext(VADriverContextP context, VAContextID context_id)
|
|||||||
object_heap_free(&driver_data->context_heap,
|
object_heap_free(&driver_data->context_heap,
|
||||||
(struct object_base *)context_object);
|
(struct object_base *)context_object);
|
||||||
|
|
||||||
rc = v4l2_request_buffers(driver_data->video_fd,
|
rc = v4l2_request_buffers(driver_data->video_fd, output_type, 0);
|
||||||
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, 0);
|
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return VA_STATUS_ERROR_OPERATION_FAILED;
|
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
rc = v4l2_request_buffers(driver_data->video_fd,
|
rc = v4l2_request_buffers(driver_data->video_fd, capture_type, 0);
|
||||||
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, 0);
|
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return VA_STATUS_ERROR_OPERATION_FAILED;
|
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
|
|||||||
+31
-5
@@ -43,7 +43,11 @@ VAStatus RequestCreateImage(VADriverContextP context, VAImageFormat *format,
|
|||||||
unsigned int destination_sizes[VIDEO_MAX_PLANES];
|
unsigned int destination_sizes[VIDEO_MAX_PLANES];
|
||||||
unsigned int destination_bytesperlines[VIDEO_MAX_PLANES];
|
unsigned int destination_bytesperlines[VIDEO_MAX_PLANES];
|
||||||
unsigned int destination_planes_count;
|
unsigned int destination_planes_count;
|
||||||
|
unsigned int planes_count;
|
||||||
|
unsigned int format_width, format_height;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
|
unsigned int capture_type;
|
||||||
|
struct video_format *video_format;
|
||||||
struct object_image *image_object;
|
struct object_image *image_object;
|
||||||
VABufferID buffer_id;
|
VABufferID buffer_id;
|
||||||
VAImageID id;
|
VAImageID id;
|
||||||
@@ -51,18 +55,39 @@ VAStatus RequestCreateImage(VADriverContextP context, VAImageFormat *format,
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = v4l2_get_format(driver_data->video_fd,
|
video_format = driver_data->video_format;
|
||||||
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, NULL, NULL,
|
if (video_format == NULL)
|
||||||
|
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
|
capture_type = v4l2_type_video_capture(video_format->v4l2_mplane);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: This should be replaced by per-pixelformat hadling to
|
||||||
|
* determine the logical plane offsets and sizes;
|
||||||
|
*/
|
||||||
|
rc = v4l2_get_format(driver_data->video_fd, capture_type,
|
||||||
|
&format_width, &format_height,
|
||||||
destination_bytesperlines, destination_sizes,
|
destination_bytesperlines, destination_sizes,
|
||||||
&destination_planes_count);
|
&planes_count);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return VA_STATUS_ERROR_OPERATION_FAILED;
|
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
|
destination_planes_count = video_format->planes_count;
|
||||||
size = 0;
|
size = 0;
|
||||||
|
|
||||||
for (i = 0; i < destination_planes_count; i++)
|
/* The size returned by V4L2 covers buffers, not logical planes. */
|
||||||
|
for (i = 0; i < planes_count; i++)
|
||||||
size += destination_sizes[i];
|
size += destination_sizes[i];
|
||||||
|
|
||||||
|
/* Here we calculate the sizes assuming NV12. */
|
||||||
|
|
||||||
|
destination_sizes[0] = destination_bytesperlines[0] * format_height;
|
||||||
|
|
||||||
|
for (i = 1; i < destination_planes_count; i++) {
|
||||||
|
destination_bytesperlines[i] = destination_bytesperlines[0];
|
||||||
|
destination_sizes[i] = destination_sizes[0] / 2;
|
||||||
|
}
|
||||||
|
|
||||||
id = object_heap_allocate(&driver_data->image_heap);
|
id = object_heap_allocate(&driver_data->image_heap);
|
||||||
image_object = IMAGE(driver_data, id);
|
image_object = IMAGE(driver_data, id);
|
||||||
if (image_object == NULL)
|
if (image_object == NULL)
|
||||||
@@ -155,10 +180,11 @@ VAStatus RequestDeriveImage(VADriverContextP context, VASurfaceID surface_id,
|
|||||||
image->pitches[i], image->width,
|
image->pitches[i], image->width,
|
||||||
i == 0 ? image->height :
|
i == 0 ? image->height :
|
||||||
image->height / 2);
|
image->height / 2);
|
||||||
else
|
else {
|
||||||
memcpy(buffer_object->data + image->offsets[i],
|
memcpy(buffer_object->data + image->offsets[i],
|
||||||
surface_object->destination_data[i],
|
surface_object->destination_data[i],
|
||||||
surface_object->destination_sizes[i]);
|
surface_object->destination_sizes[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
surface_object->status = VASurfaceReady;
|
surface_object->status = VASurfaceReady;
|
||||||
|
|||||||
+11
-4
@@ -267,10 +267,19 @@ VAStatus RequestEndPicture(VADriverContextP context, VAContextID context_id)
|
|||||||
struct object_context *context_object;
|
struct object_context *context_object;
|
||||||
struct object_config *config_object;
|
struct object_config *config_object;
|
||||||
struct object_surface *surface_object;
|
struct object_surface *surface_object;
|
||||||
|
struct video_format *video_format;
|
||||||
|
unsigned int output_type, capture_type;
|
||||||
int request_fd;
|
int request_fd;
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
video_format = driver_data->video_format;
|
||||||
|
if (video_format == NULL)
|
||||||
|
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
|
output_type = v4l2_type_video_output(video_format->v4l2_mplane);
|
||||||
|
capture_type = v4l2_type_video_capture(video_format->v4l2_mplane);
|
||||||
|
|
||||||
context_object = CONTEXT(driver_data, context_id);
|
context_object = CONTEXT(driver_data, context_id);
|
||||||
if (context_object == NULL)
|
if (context_object == NULL)
|
||||||
return VA_STATUS_ERROR_INVALID_CONTEXT;
|
return VA_STATUS_ERROR_INVALID_CONTEXT;
|
||||||
@@ -298,15 +307,13 @@ VAStatus RequestEndPicture(VADriverContextP context, VAContextID context_id)
|
|||||||
if (rc != VA_STATUS_SUCCESS)
|
if (rc != VA_STATUS_SUCCESS)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
rc = v4l2_queue_buffer(driver_data->video_fd, -1,
|
rc = v4l2_queue_buffer(driver_data->video_fd, -1, capture_type,
|
||||||
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
|
|
||||||
surface_object->destination_index, 0,
|
surface_object->destination_index, 0,
|
||||||
surface_object->destination_buffers_count);
|
surface_object->destination_buffers_count);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return VA_STATUS_ERROR_OPERATION_FAILED;
|
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
rc = v4l2_queue_buffer(driver_data->video_fd, request_fd,
|
rc = v4l2_queue_buffer(driver_data->video_fd, request_fd, output_type,
|
||||||
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
|
|
||||||
surface_object->source_index,
|
surface_object->source_index,
|
||||||
surface_object->slices_size, 1);
|
surface_object->slices_size, 1);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
|
|||||||
+1
-1
@@ -159,7 +159,7 @@ VAStatus VA_DRIVER_INIT_FUNC(VADriverContextP context)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
capabilities_required = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
|
capabilities_required = V4L2_CAP_STREAMING;
|
||||||
|
|
||||||
if ((capabilities & capabilities_required) != capabilities_required) {
|
if ((capabilities & capabilities_required) != capabilities_required) {
|
||||||
request_log("Missing required driver capabilities\n");
|
request_log("Missing required driver capabilities\n");
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "object_heap.h"
|
#include "object_heap.h"
|
||||||
|
#include "video.h"
|
||||||
#include <va/va.h>
|
#include <va/va.h>
|
||||||
|
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
|
|||||||
+48
-25
@@ -58,6 +58,8 @@ VAStatus RequestCreateSurfaces2(VADriverContextP context, unsigned int format,
|
|||||||
unsigned int destination_sizes[VIDEO_MAX_PLANES];
|
unsigned int destination_sizes[VIDEO_MAX_PLANES];
|
||||||
unsigned int destination_bytesperlines[VIDEO_MAX_PLANES];
|
unsigned int destination_bytesperlines[VIDEO_MAX_PLANES];
|
||||||
unsigned int destination_planes_count;
|
unsigned int destination_planes_count;
|
||||||
|
unsigned int format_width, format_height;
|
||||||
|
unsigned int capture_type;
|
||||||
unsigned int index_base;
|
unsigned int index_base;
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
@@ -69,13 +71,13 @@ VAStatus RequestCreateSurfaces2(VADriverContextP context, unsigned int format,
|
|||||||
return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
|
return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
|
||||||
|
|
||||||
found = v4l2_find_format(driver_data->video_fd,
|
found = v4l2_find_format(driver_data->video_fd,
|
||||||
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
|
V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
||||||
V4L2_PIX_FMT_SUNXI_TILED_NV12);
|
V4L2_PIX_FMT_SUNXI_TILED_NV12);
|
||||||
if (found)
|
if (found)
|
||||||
video_format = video_format_find(V4L2_PIX_FMT_SUNXI_TILED_NV12);
|
video_format = video_format_find(V4L2_PIX_FMT_SUNXI_TILED_NV12);
|
||||||
|
|
||||||
found = v4l2_find_format(driver_data->video_fd,
|
found = v4l2_find_format(driver_data->video_fd,
|
||||||
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
|
V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
||||||
V4L2_PIX_FMT_NV12);
|
V4L2_PIX_FMT_NV12);
|
||||||
if (found)
|
if (found)
|
||||||
video_format = video_format_find(V4L2_PIX_FMT_NV12);
|
video_format = video_format_find(V4L2_PIX_FMT_NV12);
|
||||||
@@ -85,21 +87,22 @@ VAStatus RequestCreateSurfaces2(VADriverContextP context, unsigned int format,
|
|||||||
|
|
||||||
driver_data->video_format = video_format;
|
driver_data->video_format = video_format;
|
||||||
|
|
||||||
rc = v4l2_set_format(driver_data->video_fd,
|
capture_type = v4l2_type_video_capture(video_format->v4l2_mplane);
|
||||||
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
|
|
||||||
|
rc = v4l2_set_format(driver_data->video_fd, capture_type,
|
||||||
video_format->v4l2_format, width, height);
|
video_format->v4l2_format, width, height);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return VA_STATUS_ERROR_OPERATION_FAILED;
|
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
rc = v4l2_get_format(driver_data->video_fd,
|
rc = v4l2_get_format(driver_data->video_fd, capture_type, &format_width,
|
||||||
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, NULL, NULL,
|
&format_height, destination_bytesperlines,
|
||||||
destination_bytesperlines, destination_sizes,
|
destination_sizes, NULL);
|
||||||
&destination_planes_count);
|
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return VA_STATUS_ERROR_OPERATION_FAILED;
|
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
rc = v4l2_create_buffers(driver_data->video_fd,
|
destination_planes_count = video_format->planes_count;
|
||||||
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
|
|
||||||
|
rc = v4l2_create_buffers(driver_data->video_fd, capture_type,
|
||||||
surfaces_count, &index_base);
|
surfaces_count, &index_base);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
@@ -112,8 +115,7 @@ VAStatus RequestCreateSurfaces2(VADriverContextP context, unsigned int format,
|
|||||||
if (surface_object == NULL)
|
if (surface_object == NULL)
|
||||||
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
|
|
||||||
rc = v4l2_query_buffer(driver_data->video_fd,
|
rc = v4l2_query_buffer(driver_data->video_fd, capture_type,
|
||||||
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
|
|
||||||
index,
|
index,
|
||||||
surface_object->destination_map_lengths,
|
surface_object->destination_map_lengths,
|
||||||
surface_object->destination_map_offsets,
|
surface_object->destination_map_offsets,
|
||||||
@@ -133,7 +135,19 @@ VAStatus RequestCreateSurfaces2(VADriverContextP context, unsigned int format,
|
|||||||
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: Handle this per-pixelformat, trying to generalize it
|
||||||
|
* is not a reasonable approach. The final description should be
|
||||||
|
* in terms of (logical) planes.
|
||||||
|
*/
|
||||||
|
|
||||||
if (video_format->v4l2_buffers_count == 1) {
|
if (video_format->v4l2_buffers_count == 1) {
|
||||||
|
destination_sizes[0] = destination_bytesperlines[0] *
|
||||||
|
format_height;
|
||||||
|
|
||||||
|
for (j = 1; j < destination_planes_count; j++)
|
||||||
|
destination_sizes[j] = destination_sizes[0] / 2;
|
||||||
|
|
||||||
for (j = 0; j < destination_planes_count; j++) {
|
for (j = 0; j < destination_planes_count; j++) {
|
||||||
surface_object->destination_offsets[j] =
|
surface_object->destination_offsets[j] =
|
||||||
j > 0 ? destination_sizes[j - 1] : 0;
|
j > 0 ? destination_sizes[j - 1] : 0;
|
||||||
@@ -143,7 +157,7 @@ VAStatus RequestCreateSurfaces2(VADriverContextP context, unsigned int format,
|
|||||||
surface_object->destination_sizes[j] =
|
surface_object->destination_sizes[j] =
|
||||||
destination_sizes[j];
|
destination_sizes[j];
|
||||||
surface_object->destination_bytesperlines[j] =
|
surface_object->destination_bytesperlines[j] =
|
||||||
destination_bytesperlines[j];
|
destination_bytesperlines[0];
|
||||||
}
|
}
|
||||||
} else if (video_format->v4l2_buffers_count == destination_planes_count) {
|
} else if (video_format->v4l2_buffers_count == destination_planes_count) {
|
||||||
for (j = 0; j < destination_planes_count; j++) {
|
for (j = 0; j < destination_planes_count; j++) {
|
||||||
@@ -233,9 +247,20 @@ VAStatus RequestSyncSurface(VADriverContextP context, VASurfaceID surface_id)
|
|||||||
struct request_data *driver_data = context->pDriverData;
|
struct request_data *driver_data = context->pDriverData;
|
||||||
struct object_surface *surface_object;
|
struct object_surface *surface_object;
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
|
struct video_format *video_format;
|
||||||
|
unsigned int output_type, capture_type;
|
||||||
int request_fd = -1;
|
int request_fd = -1;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
video_format = driver_data->video_format;
|
||||||
|
if (video_format == NULL) {
|
||||||
|
status = VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
output_type = v4l2_type_video_output(video_format->v4l2_mplane);
|
||||||
|
capture_type = v4l2_type_video_capture(video_format->v4l2_mplane);
|
||||||
|
|
||||||
surface_object = SURFACE(driver_data, surface_id);
|
surface_object = SURFACE(driver_data, surface_id);
|
||||||
if (surface_object == NULL) {
|
if (surface_object == NULL) {
|
||||||
status = VA_STATUS_ERROR_INVALID_SURFACE;
|
status = VA_STATUS_ERROR_INVALID_SURFACE;
|
||||||
@@ -271,16 +296,14 @@ VAStatus RequestSyncSurface(VADriverContextP context, VASurfaceID surface_id)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = v4l2_dequeue_buffer(driver_data->video_fd, -1,
|
rc = v4l2_dequeue_buffer(driver_data->video_fd, -1, output_type,
|
||||||
V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
|
|
||||||
surface_object->source_index, 1);
|
surface_object->source_index, 1);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
status = VA_STATUS_ERROR_OPERATION_FAILED;
|
status = VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = v4l2_dequeue_buffer(driver_data->video_fd, -1,
|
rc = v4l2_dequeue_buffer(driver_data->video_fd, -1, capture_type,
|
||||||
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
|
|
||||||
surface_object->destination_index,
|
surface_object->destination_index,
|
||||||
surface_object->destination_buffers_count);
|
surface_object->destination_buffers_count);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
@@ -433,11 +456,16 @@ VAStatus RequestExportSurfaceHandle(VADriverContextP context,
|
|||||||
int *export_fds = NULL;
|
int *export_fds = NULL;
|
||||||
unsigned int export_fds_count;
|
unsigned int export_fds_count;
|
||||||
unsigned int planes_count;
|
unsigned int planes_count;
|
||||||
|
unsigned int capture_type;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
video_format = driver_data->video_format;
|
||||||
|
if (video_format == NULL)
|
||||||
|
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
if (mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2)
|
if (mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2)
|
||||||
return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
|
return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
|
||||||
|
|
||||||
@@ -448,8 +476,9 @@ VAStatus RequestExportSurfaceHandle(VADriverContextP context,
|
|||||||
export_fds_count = surface_object->destination_buffers_count;
|
export_fds_count = surface_object->destination_buffers_count;
|
||||||
export_fds = malloc(export_fds_count * sizeof(*export_fds));
|
export_fds = malloc(export_fds_count * sizeof(*export_fds));
|
||||||
|
|
||||||
rc = v4l2_export_buffer(driver_data->video_fd,
|
capture_type = v4l2_type_video_capture(video_format->v4l2_mplane);
|
||||||
V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
|
|
||||||
|
rc = v4l2_export_buffer(driver_data->video_fd, capture_type,
|
||||||
surface_object->destination_index, O_RDONLY,
|
surface_object->destination_index, O_RDONLY,
|
||||||
export_fds, export_fds_count);
|
export_fds, export_fds_count);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
@@ -459,12 +488,6 @@ VAStatus RequestExportSurfaceHandle(VADriverContextP context,
|
|||||||
|
|
||||||
planes_count = surface_object->destination_planes_count;
|
planes_count = surface_object->destination_planes_count;
|
||||||
|
|
||||||
video_format = driver_data->video_format;
|
|
||||||
if (video_format == NULL) {
|
|
||||||
status = VA_STATUS_ERROR_OPERATION_FAILED;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
surface_descriptor->fourcc = VA_FOURCC_NV12;
|
surface_descriptor->fourcc = VA_FOURCC_NV12;
|
||||||
surface_descriptor->width = surface_object->width;
|
surface_descriptor->width = surface_object->width;
|
||||||
surface_descriptor->height = surface_object->height;
|
surface_descriptor->height = surface_object->height;
|
||||||
|
|||||||
+127
-30
@@ -32,6 +32,42 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "v4l2.h"
|
#include "v4l2.h"
|
||||||
|
|
||||||
|
static bool v4l2_type_is_output(unsigned int type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
|
||||||
|
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool v4l2_type_is_mplane(unsigned int type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
|
||||||
|
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int v4l2_type_video_output(bool mplane)
|
||||||
|
{
|
||||||
|
return mplane ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
|
||||||
|
V4L2_BUF_TYPE_VIDEO_OUTPUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int v4l2_type_video_capture(bool mplane)
|
||||||
|
{
|
||||||
|
return mplane ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
|
||||||
|
V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
|
}
|
||||||
|
|
||||||
int v4l2_query_capabilities(int video_fd, unsigned int *capabilities)
|
int v4l2_query_capabilities(int video_fd, unsigned int *capabilities)
|
||||||
{
|
{
|
||||||
struct v4l2_capability capability;
|
struct v4l2_capability capability;
|
||||||
@@ -53,6 +89,30 @@ int v4l2_query_capabilities(int video_fd, unsigned int *capabilities)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void v4l2_setup_format(struct v4l2_format *format, unsigned int type,
|
||||||
|
unsigned int width, unsigned int height,
|
||||||
|
unsigned int pixelformat)
|
||||||
|
{
|
||||||
|
unsigned int sizeimage;
|
||||||
|
|
||||||
|
memset(format, 0, sizeof(*format));
|
||||||
|
format->type = type;
|
||||||
|
|
||||||
|
sizeimage = v4l2_type_is_output(type) ? SOURCE_SIZE_MAX : 0;
|
||||||
|
|
||||||
|
if (v4l2_type_is_mplane(type)) {
|
||||||
|
format->fmt.pix_mp.width = width;
|
||||||
|
format->fmt.pix_mp.height = height;
|
||||||
|
format->fmt.pix_mp.plane_fmt[0].sizeimage = sizeimage;
|
||||||
|
format->fmt.pix_mp.pixelformat = pixelformat;
|
||||||
|
} else {
|
||||||
|
format->fmt.pix.width = width;
|
||||||
|
format->fmt.pix.height = height;
|
||||||
|
format->fmt.pix.sizeimage = sizeimage;
|
||||||
|
format->fmt.pix.pixelformat = pixelformat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool v4l2_find_format(int video_fd, unsigned int type, unsigned int pixelformat)
|
bool v4l2_find_format(int video_fd, unsigned int type, unsigned int pixelformat)
|
||||||
{
|
{
|
||||||
struct v4l2_fmtdesc fmtdesc;
|
struct v4l2_fmtdesc fmtdesc;
|
||||||
@@ -76,19 +136,31 @@ bool v4l2_find_format(int video_fd, unsigned int type, unsigned int pixelformat)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int v4l2_try_format(int video_fd, unsigned int type, unsigned int width,
|
||||||
|
unsigned int height, unsigned int pixelformat)
|
||||||
|
{
|
||||||
|
struct v4l2_format format;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
v4l2_setup_format(&format, type, width, height, pixelformat);
|
||||||
|
|
||||||
|
rc = ioctl(video_fd, VIDIOC_TRY_FMT, &format);
|
||||||
|
if (rc < 0) {
|
||||||
|
request_log("Unable to try format for type %d: %s\n", type,
|
||||||
|
strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int v4l2_set_format(int video_fd, unsigned int type, unsigned int pixelformat,
|
int v4l2_set_format(int video_fd, unsigned int type, unsigned int pixelformat,
|
||||||
unsigned int width, unsigned int height)
|
unsigned int width, unsigned int height)
|
||||||
{
|
{
|
||||||
struct v4l2_format format;
|
struct v4l2_format format;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
memset(&format, 0, sizeof(format));
|
v4l2_setup_format(&format, type, width, height, pixelformat);
|
||||||
format.type = type;
|
|
||||||
format.fmt.pix_mp.width = width;
|
|
||||||
format.fmt.pix_mp.height = height;
|
|
||||||
format.fmt.pix_mp.plane_fmt[0].sizeimage =
|
|
||||||
type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ? SOURCE_SIZE_MAX : 0;
|
|
||||||
format.fmt.pix_mp.pixelformat = pixelformat;
|
|
||||||
|
|
||||||
rc = ioctl(video_fd, VIDIOC_S_FMT, &format);
|
rc = ioctl(video_fd, VIDIOC_S_FMT, &format);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
@@ -119,29 +191,46 @@ int v4l2_get_format(int video_fd, unsigned int type, unsigned int *width,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = format.fmt.pix_mp.num_planes;
|
if (v4l2_type_is_mplane(type)) {
|
||||||
|
count = format.fmt.pix_mp.num_planes;
|
||||||
|
|
||||||
if (width != NULL)
|
if (width != NULL)
|
||||||
*width = format.fmt.pix_mp.width;
|
*width = format.fmt.pix_mp.width;
|
||||||
|
|
||||||
if (height != NULL)
|
if (height != NULL)
|
||||||
*height = format.fmt.pix_mp.height;
|
*height = format.fmt.pix_mp.height;
|
||||||
|
|
||||||
if (planes_count != NULL)
|
if (planes_count != NULL)
|
||||||
if (*planes_count > 0 && *planes_count < count)
|
if (*planes_count > 0 && *planes_count < count)
|
||||||
count = *planes_count;
|
count = *planes_count;
|
||||||
|
|
||||||
if (bytesperline != NULL)
|
if (bytesperline != NULL)
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
bytesperline[i] =
|
bytesperline[i] =
|
||||||
format.fmt.pix_mp.plane_fmt[i].bytesperline;
|
format.fmt.pix_mp.plane_fmt[i].bytesperline;
|
||||||
|
|
||||||
if (sizes != NULL)
|
if (sizes != NULL)
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
sizes[i] = format.fmt.pix_mp.plane_fmt[i].sizeimage;
|
sizes[i] = format.fmt.pix_mp.plane_fmt[i].sizeimage;
|
||||||
|
|
||||||
if (planes_count != NULL)
|
if (planes_count != NULL)
|
||||||
*planes_count = count;
|
*planes_count = count;
|
||||||
|
} else {
|
||||||
|
if (width != NULL)
|
||||||
|
*width = format.fmt.pix.width;
|
||||||
|
|
||||||
|
if (height != NULL)
|
||||||
|
*height = format.fmt.pix.height;
|
||||||
|
|
||||||
|
if (bytesperline != NULL)
|
||||||
|
bytesperline[0] = format.fmt.pix.bytesperline;
|
||||||
|
|
||||||
|
if (sizes != NULL)
|
||||||
|
sizes[0] = format.fmt.pix.sizeimage;
|
||||||
|
|
||||||
|
if (planes_count != NULL)
|
||||||
|
*planes_count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -201,13 +290,21 @@ int v4l2_query_buffer(int video_fd, unsigned int type, unsigned int index,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lengths != NULL)
|
if (v4l2_type_is_mplane(type)) {
|
||||||
for (i = 0; i < buffer.length; i++)
|
if (lengths != NULL)
|
||||||
lengths[i] = buffer.m.planes[i].length;
|
for (i = 0; i < buffer.length; i++)
|
||||||
|
lengths[i] = buffer.m.planes[i].length;
|
||||||
|
|
||||||
if (offsets != NULL)
|
if (offsets != NULL)
|
||||||
for (i = 0; i < buffer.length; i++)
|
for (i = 0; i < buffer.length; i++)
|
||||||
offsets[i] = buffer.m.planes[i].m.mem_offset;
|
offsets[i] = buffer.m.planes[i].m.mem_offset;
|
||||||
|
} else {
|
||||||
|
if (lengths != NULL)
|
||||||
|
lengths[0] = buffer.length;
|
||||||
|
|
||||||
|
if (offsets != NULL)
|
||||||
|
offsets[0] = buffer.m.offset;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
|
|
||||||
#define SOURCE_SIZE_MAX (1024 * 1024)
|
#define SOURCE_SIZE_MAX (1024 * 1024)
|
||||||
|
|
||||||
|
unsigned int v4l2_type_video_output(bool mplane);
|
||||||
|
unsigned int v4l2_type_video_capture(bool mplane);
|
||||||
int v4l2_query_capabilities(int video_fd, unsigned int *capabilities);
|
int v4l2_query_capabilities(int video_fd, unsigned int *capabilities);
|
||||||
bool v4l2_find_format(int video_fd, unsigned int type,
|
bool v4l2_find_format(int video_fd, unsigned int type,
|
||||||
unsigned int pixelformat);
|
unsigned int pixelformat);
|
||||||
|
|||||||
+4
-2
@@ -39,18 +39,20 @@ static struct video_format formats[] = {
|
|||||||
.description = "NV12 YUV",
|
.description = "NV12 YUV",
|
||||||
.v4l2_format = V4L2_PIX_FMT_NV12,
|
.v4l2_format = V4L2_PIX_FMT_NV12,
|
||||||
.v4l2_buffers_count = 1,
|
.v4l2_buffers_count = 1,
|
||||||
|
.v4l2_mplane = false,
|
||||||
.drm_format = DRM_FORMAT_NV12,
|
.drm_format = DRM_FORMAT_NV12,
|
||||||
.drm_modifier = DRM_FORMAT_MOD_NONE,
|
.drm_modifier = DRM_FORMAT_MOD_NONE,
|
||||||
.drm_planes_count = 2,
|
.planes_count = 2,
|
||||||
.bpp = 16,
|
.bpp = 16,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.description = "Sunxi tiled NV12 YUV",
|
.description = "Sunxi tiled NV12 YUV",
|
||||||
.v4l2_format = V4L2_PIX_FMT_SUNXI_TILED_NV12,
|
.v4l2_format = V4L2_PIX_FMT_SUNXI_TILED_NV12,
|
||||||
.v4l2_buffers_count = 1,
|
.v4l2_buffers_count = 1,
|
||||||
|
.v4l2_mplane = false,
|
||||||
.drm_format = DRM_FORMAT_NV12,
|
.drm_format = DRM_FORMAT_NV12,
|
||||||
.drm_modifier = DRM_FORMAT_MOD_ALLWINNER_MB32_TILED,
|
.drm_modifier = DRM_FORMAT_MOD_ALLWINNER_MB32_TILED,
|
||||||
.drm_planes_count = 2,
|
.planes_count = 2,
|
||||||
.bpp = 16
|
.bpp = 16
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
+2
-1
@@ -31,9 +31,10 @@ struct video_format {
|
|||||||
char *description;
|
char *description;
|
||||||
unsigned int v4l2_format;
|
unsigned int v4l2_format;
|
||||||
unsigned int v4l2_buffers_count;
|
unsigned int v4l2_buffers_count;
|
||||||
|
bool v4l2_mplane;
|
||||||
unsigned int drm_format;
|
unsigned int drm_format;
|
||||||
uint64_t drm_modifier;
|
uint64_t drm_modifier;
|
||||||
unsigned int drm_planes_count;
|
unsigned int planes_count;
|
||||||
unsigned int bpp;
|
unsigned int bpp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user