forked from marfrit/libva-v4l2-request-fourier
Centralize buffer-related ressources in surface object and avoid dynamic indexes
Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
This commit is contained in:
+5
-37
@@ -46,15 +46,9 @@ VAStatus SunxiCedrusCreateBuffer(VADriverContextP context,
|
|||||||
struct sunxi_cedrus_driver_data *driver_data =
|
struct sunxi_cedrus_driver_data *driver_data =
|
||||||
(struct sunxi_cedrus_driver_data *) context->pDriverData;
|
(struct sunxi_cedrus_driver_data *) context->pDriverData;
|
||||||
struct object_buffer *buffer_object = NULL;
|
struct object_buffer *buffer_object = NULL;
|
||||||
struct object_context *context_object;
|
|
||||||
void *buffer_data;
|
void *buffer_data;
|
||||||
void *map_data;
|
|
||||||
unsigned int map_size;
|
|
||||||
unsigned int length;
|
|
||||||
unsigned int offset;
|
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
VABufferID id;
|
VABufferID id;
|
||||||
int rc;
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case VAPictureParameterBufferType:
|
case VAPictureParameterBufferType:
|
||||||
@@ -76,42 +70,20 @@ VAStatus SunxiCedrusCreateBuffer(VADriverContextP context,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(buffer_object->type == VASliceDataBufferType) {
|
buffer_data = malloc(size * count);
|
||||||
context_object = CONTEXT(context_id);
|
if (buffer_data == NULL) {
|
||||||
if (context_object == NULL) {
|
|
||||||
status = VA_STATUS_ERROR_INVALID_CONTEXT;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = v4l2_request_buffer(driver_data->video_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, context_object->num_rendered_surfaces % INPUT_BUFFERS_NB, &length, &offset);
|
|
||||||
if (rc < 0) {
|
|
||||||
status = VA_STATUS_ERROR_ALLOCATION_FAILED;
|
status = VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
map_size = driver_data->slice_offset[context_object->num_rendered_surfaces % INPUT_BUFFERS_NB] + size * count;
|
if (data != NULL)
|
||||||
map_data = mmap(NULL, map_size, PROT_READ | PROT_WRITE, MAP_SHARED,
|
memcpy(buffer_data, data, size * count);
|
||||||
driver_data->video_fd, offset);
|
|
||||||
|
|
||||||
buffer_data = map_data + driver_data->slice_offset[context_object->num_rendered_surfaces % INPUT_BUFFERS_NB];
|
|
||||||
driver_data->slice_offset[context_object->num_rendered_surfaces % INPUT_BUFFERS_NB] += size * count;
|
|
||||||
} else {
|
|
||||||
buffer_data = malloc(size * count);
|
|
||||||
map_size = 0;
|
|
||||||
map_data = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data)
|
|
||||||
memcpy(map_data, data, size * count);
|
|
||||||
|
|
||||||
buffer_object->type = type;
|
buffer_object->type = type;
|
||||||
buffer_object->initial_count = count;
|
buffer_object->initial_count = count;
|
||||||
buffer_object->count = count;
|
buffer_object->count = count;
|
||||||
|
|
||||||
buffer_object->data = buffer_data;
|
buffer_object->data = buffer_data;
|
||||||
buffer_object->map = map_data;
|
|
||||||
buffer_object->size = size;
|
buffer_object->size = size;
|
||||||
buffer_object->map_size = map_size;
|
|
||||||
|
|
||||||
*buffer_id = id;
|
*buffer_id = id;
|
||||||
|
|
||||||
@@ -137,12 +109,8 @@ VAStatus SunxiCedrusDestroyBuffer(VADriverContextP context,
|
|||||||
if (buffer_object == NULL)
|
if (buffer_object == NULL)
|
||||||
return VA_STATUS_ERROR_INVALID_BUFFER;
|
return VA_STATUS_ERROR_INVALID_BUFFER;
|
||||||
|
|
||||||
if (buffer_object->data != NULL) {
|
if (buffer_object->data != NULL)
|
||||||
if (buffer_object->type != VASliceDataBufferType)
|
|
||||||
free(buffer_object->data);
|
free(buffer_object->data);
|
||||||
else if (buffer_object->map != NULL && buffer_object->map_size > 0)
|
|
||||||
munmap(buffer_object->map, buffer_object->map_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
object_heap_free(&driver_data->buffer_heap, (struct object_base *) buffer_object);
|
object_heap_free(&driver_data->buffer_heap, (struct object_base *) buffer_object);
|
||||||
|
|
||||||
|
|||||||
@@ -43,9 +43,6 @@ struct object_buffer {
|
|||||||
|
|
||||||
void *data;
|
void *data;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
|
|
||||||
void *map;
|
|
||||||
unsigned int map_size;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VAStatus SunxiCedrusCreateBuffer(VADriverContextP context,
|
VAStatus SunxiCedrusCreateBuffer(VADriverContextP context,
|
||||||
|
|||||||
+39
-17
@@ -34,6 +34,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
|
|
||||||
@@ -49,6 +50,9 @@ VAStatus SunxiCedrusCreateContext(VADriverContextP context,
|
|||||||
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;
|
||||||
|
unsigned int length;
|
||||||
|
unsigned int offset;
|
||||||
|
void *source_data = MAP_FAILED;
|
||||||
VASurfaceID *ids = NULL;
|
VASurfaceID *ids = NULL;
|
||||||
VAContextID id;
|
VAContextID id;
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
@@ -69,22 +73,6 @@ VAStatus SunxiCedrusCreateContext(VADriverContextP context,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ids = malloc(surfaces_count * sizeof(VASurfaceID));
|
|
||||||
if (ids == NULL) {
|
|
||||||
status = VA_STATUS_ERROR_ALLOCATION_FAILED;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < surfaces_count; i++) {
|
|
||||||
surface_object = SURFACE(surfaces_ids[i]);
|
|
||||||
if (surface_object == NULL) {
|
|
||||||
status = VA_STATUS_ERROR_INVALID_SURFACE;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
ids[i] = surfaces_ids[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (config_object->profile) {
|
switch (config_object->profile) {
|
||||||
case VAProfileMPEG2Simple:
|
case VAProfileMPEG2Simple:
|
||||||
case VAProfileMPEG2Main:
|
case VAProfileMPEG2Main:
|
||||||
@@ -101,12 +89,44 @@ VAStatus SunxiCedrusCreateContext(VADriverContextP context,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = v4l2_create_buffers(driver_data->video_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, INPUT_BUFFERS_NB);
|
rc = v4l2_create_buffers(driver_data->video_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, surfaces_count);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
status = VA_STATUS_ERROR_ALLOCATION_FAILED;
|
status = VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ids = malloc(surfaces_count * sizeof(VASurfaceID));
|
||||||
|
if (ids == NULL) {
|
||||||
|
status = VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < surfaces_count; i++) {
|
||||||
|
surface_object = SURFACE(surfaces_ids[i]);
|
||||||
|
if (surface_object == NULL) {
|
||||||
|
status = VA_STATUS_ERROR_INVALID_SURFACE;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = v4l2_request_buffer(driver_data->video_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, i, &length, &offset);
|
||||||
|
if (rc < 0) {
|
||||||
|
status = VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
source_data = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, driver_data->video_fd, offset);
|
||||||
|
if (source_data == MAP_FAILED) {
|
||||||
|
status = VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
surface_object->source_index = i;
|
||||||
|
surface_object->source_data = source_data;
|
||||||
|
surface_object->source_size = length;
|
||||||
|
|
||||||
|
ids[i] = surfaces_ids[i];
|
||||||
|
}
|
||||||
|
|
||||||
rc = v4l2_set_stream(driver_data->video_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, true);
|
rc = v4l2_set_stream(driver_data->video_fd, 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;
|
||||||
@@ -128,6 +148,8 @@ VAStatus SunxiCedrusCreateContext(VADriverContextP context,
|
|||||||
goto complete;
|
goto complete;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
if (source_data != MAP_FAILED)
|
||||||
|
munmap(source_data, length);
|
||||||
if (ids != NULL)
|
if (ids != NULL)
|
||||||
free(ids);
|
free(ids);
|
||||||
|
|
||||||
|
|||||||
@@ -30,9 +30,6 @@
|
|||||||
|
|
||||||
#include "object_heap.h"
|
#include "object_heap.h"
|
||||||
|
|
||||||
#define INPUT_BUFFER_MAX_SIZE 131072
|
|
||||||
#define INPUT_BUFFERS_NB 6
|
|
||||||
|
|
||||||
#define CONTEXT(id) ((struct object_context *) object_heap_lookup(&driver_data->context_heap, id))
|
#define CONTEXT(id) ((struct object_context *) object_heap_lookup(&driver_data->context_heap, id))
|
||||||
#define CONTEXT_ID_OFFSET 0x02000000
|
#define CONTEXT_ID_OFFSET 0x02000000
|
||||||
|
|
||||||
@@ -47,9 +44,6 @@ struct object_context {
|
|||||||
int picture_width;
|
int picture_width;
|
||||||
int picture_height;
|
int picture_height;
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
struct v4l2_ctrl_mpeg2_frame_hdr mpeg2_frame_hdr;
|
|
||||||
uint32_t num_rendered_surfaces;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VAStatus SunxiCedrusCreateContext(VADriverContextP context,
|
VAStatus SunxiCedrusCreateContext(VADriverContextP context,
|
||||||
|
|||||||
+2
-2
@@ -125,8 +125,8 @@ VAStatus SunxiCedrusDeriveImage(VADriverContextP context,
|
|||||||
return VA_STATUS_ERROR_INVALID_BUFFER;
|
return VA_STATUS_ERROR_INVALID_BUFFER;
|
||||||
|
|
||||||
/* TODO: Use an appropriate DRM plane instead */
|
/* TODO: Use an appropriate DRM plane instead */
|
||||||
tiled_to_planar(driver_data->luma_bufs[surface_object->output_buf_index], buffer_object->data, image->pitches[0], image->width, image->height);
|
tiled_to_planar(surface_object->destination_data[0], buffer_object->data, image->pitches[0], image->width, image->height);
|
||||||
tiled_to_planar(driver_data->chroma_bufs[surface_object->output_buf_index], buffer_object->data + image->width*image->height, image->pitches[1], image->width, image->height/2);
|
tiled_to_planar(surface_object->destination_data[1], buffer_object->data + image->width*image->height, image->pitches[1], image->width, image->height/2);
|
||||||
|
|
||||||
surface_object->status = VASurfaceReady;
|
surface_object->status = VASurfaceReady;
|
||||||
|
|
||||||
|
|||||||
+17
-5
@@ -39,7 +39,7 @@ int mpeg2_fill_picture_parameters(struct sunxi_cedrus_driver_data *driver_data,
|
|||||||
struct object_surface *surface_object,
|
struct object_surface *surface_object,
|
||||||
VAPictureParameterBufferMPEG2 *parameters)
|
VAPictureParameterBufferMPEG2 *parameters)
|
||||||
{
|
{
|
||||||
struct v4l2_ctrl_mpeg2_frame_hdr *header = &context_object->mpeg2_frame_hdr;
|
struct v4l2_ctrl_mpeg2_frame_hdr *header = &surface_object->mpeg2_header;
|
||||||
struct object_surface *forward_reference_surface;
|
struct object_surface *forward_reference_surface;
|
||||||
struct object_surface *backward_reference_surface;
|
struct object_surface *backward_reference_surface;
|
||||||
|
|
||||||
@@ -65,15 +65,15 @@ int mpeg2_fill_picture_parameters(struct sunxi_cedrus_driver_data *driver_data,
|
|||||||
|
|
||||||
forward_reference_surface = SURFACE(parameters->forward_reference_picture);
|
forward_reference_surface = SURFACE(parameters->forward_reference_picture);
|
||||||
if (forward_reference_surface != NULL)
|
if (forward_reference_surface != NULL)
|
||||||
header->forward_ref_index = forward_reference_surface->output_buf_index;
|
header->forward_ref_index = forward_reference_surface->destination_index;
|
||||||
else
|
else
|
||||||
header->forward_ref_index = surface_object->output_buf_index;
|
header->forward_ref_index = surface_object->destination_index;
|
||||||
|
|
||||||
backward_reference_surface = SURFACE(parameters->backward_reference_picture);
|
backward_reference_surface = SURFACE(parameters->backward_reference_picture);
|
||||||
if (backward_reference_surface != NULL)
|
if (backward_reference_surface != NULL)
|
||||||
header->backward_ref_index = backward_reference_surface->output_buf_index;
|
header->backward_ref_index = backward_reference_surface->destination_index;
|
||||||
else
|
else
|
||||||
header->backward_ref_index = surface_object->output_buf_index;
|
header->backward_ref_index = surface_object->destination_index;
|
||||||
|
|
||||||
header->width = context_object->picture_width;
|
header->width = context_object->picture_width;
|
||||||
header->height = context_object->picture_height;
|
header->height = context_object->picture_height;
|
||||||
@@ -85,5 +85,17 @@ int mpeg2_fill_slice_data(struct sunxi_cedrus_driver_data *driver_data,
|
|||||||
struct object_context *context_object,
|
struct object_context *context_object,
|
||||||
struct object_surface *surface_object, void *data, unsigned int size)
|
struct object_surface *surface_object, void *data, unsigned int size)
|
||||||
{
|
{
|
||||||
|
unsigned char *p = (unsigned char *) surface_object->source_data +
|
||||||
|
surface_object->slices_size;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since there is no guarantee that the allocation order is the same as
|
||||||
|
* the submission order (via RenderPicture), we can't use a V4L2 buffer
|
||||||
|
* directly and have to copy from a regular buffer.
|
||||||
|
* */
|
||||||
|
memcpy(p, data, size);
|
||||||
|
|
||||||
|
surface_object->slices_size += size;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-11
@@ -65,9 +65,7 @@ VAStatus SunxiCedrusBeginPicture(VADriverContextP context,
|
|||||||
SunxiCedrusSyncSurface(context, surface_id);
|
SunxiCedrusSyncSurface(context, surface_id);
|
||||||
|
|
||||||
surface_object->status = VASurfaceRendering;
|
surface_object->status = VASurfaceRendering;
|
||||||
surface_object->input_buf_index = context_object->num_rendered_surfaces % INPUT_BUFFERS_NB;
|
|
||||||
context_object->render_surface_id = surface_id;
|
context_object->render_surface_id = surface_id;
|
||||||
context_object->num_rendered_surfaces++;
|
|
||||||
|
|
||||||
return VA_STATUS_SUCCESS;
|
return VA_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -160,24 +158,24 @@ VAStatus SunxiCedrusEndPicture(VADriverContextP context,
|
|||||||
if (surface_object == NULL)
|
if (surface_object == NULL)
|
||||||
return VA_STATUS_ERROR_INVALID_SURFACE;
|
return VA_STATUS_ERROR_INVALID_SURFACE;
|
||||||
|
|
||||||
request_fd = driver_data->request_fds[surface_object->input_buf_index];
|
request_fd = surface_object->request_fd;
|
||||||
if (request_fd < 0) {
|
if (request_fd < 0) {
|
||||||
request_fd = media_request_alloc(driver_data->media_fd);
|
request_fd = media_request_alloc(driver_data->media_fd);
|
||||||
if (request_fd < 0)
|
if (request_fd < 0)
|
||||||
return VA_STATUS_ERROR_OPERATION_FAILED;
|
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
driver_data->request_fds[surface_object->input_buf_index] = request_fd;
|
surface_object->request_fd = request_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (config_object->profile) {
|
switch (config_object->profile) {
|
||||||
case VAProfileMPEG2Simple:
|
case VAProfileMPEG2Simple:
|
||||||
case VAProfileMPEG2Main:
|
case VAProfileMPEG2Main:
|
||||||
context_object->mpeg2_frame_hdr.slice_pos = 0;
|
surface_object->mpeg2_header.slice_pos = 0;
|
||||||
context_object->mpeg2_frame_hdr.slice_len = driver_data->slice_offset[surface_object->input_buf_index] * 8;
|
surface_object->mpeg2_header.slice_len = surface_object->slices_size * 8;
|
||||||
|
|
||||||
control_id = V4L2_CID_MPEG_VIDEO_MPEG2_FRAME_HDR;
|
control_id = V4L2_CID_MPEG_VIDEO_MPEG2_FRAME_HDR;
|
||||||
control_data = &context_object->mpeg2_frame_hdr;
|
control_data = &surface_object->mpeg2_header;
|
||||||
control_size = sizeof(context_object->mpeg2_frame_hdr);
|
control_size = sizeof(surface_object->mpeg2_header);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -188,15 +186,15 @@ VAStatus SunxiCedrusEndPicture(VADriverContextP context,
|
|||||||
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, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, surface_object->output_buf_index, 0);
|
rc = v4l2_queue_buffer(driver_data->video_fd, request_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, surface_object->destination_index, 0);
|
||||||
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, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, surface_object->input_buf_index, driver_data->slice_offset[surface_object->input_buf_index]);
|
rc = v4l2_queue_buffer(driver_data->video_fd, request_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, surface_object->source_index, surface_object->slices_size);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return VA_STATUS_ERROR_OPERATION_FAILED;
|
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
driver_data->slice_offset[surface_object->input_buf_index] = 0;
|
surface_object->slices_size = 0;
|
||||||
|
|
||||||
context_object->render_surface_id = VA_INVALID_ID;
|
context_object->render_surface_id = VA_INVALID_ID;
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ VAStatus VA_DRIVER_INIT_FUNC(VADriverContextP context)
|
|||||||
struct VADriverVTable *vtable = context->vtable;
|
struct VADriverVTable *vtable = context->vtable;
|
||||||
struct v4l2_capability capability;
|
struct v4l2_capability capability;
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
unsigned int i;
|
|
||||||
int video_fd = -1;
|
int video_fd = -1;
|
||||||
int media_fd = -1;
|
int media_fd = -1;
|
||||||
char *video_path;
|
char *video_path;
|
||||||
@@ -160,11 +159,6 @@ VAStatus VA_DRIVER_INIT_FUNC(VADriverContextP context)
|
|||||||
driver_data->video_fd = video_fd;
|
driver_data->video_fd = video_fd;
|
||||||
driver_data->media_fd = media_fd;
|
driver_data->media_fd = media_fd;
|
||||||
|
|
||||||
for (i = 0; i < INPUT_BUFFERS_NB; i++) {
|
|
||||||
driver_data->request_fds[i] = -1;
|
|
||||||
driver_data->slice_offset[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = VA_STATUS_SUCCESS;
|
status = VA_STATUS_SUCCESS;
|
||||||
goto complete;
|
goto complete;
|
||||||
|
|
||||||
@@ -191,11 +185,6 @@ VAStatus SunxiCedrusTerminate(VADriverContextP context)
|
|||||||
struct object_context *context_object;
|
struct object_context *context_object;
|
||||||
struct object_config *config_object;
|
struct object_config *config_object;
|
||||||
object_heap_iterator iterator;
|
object_heap_iterator iterator;
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < INPUT_BUFFERS_NB; i++)
|
|
||||||
if (driver_data->request_fds[i] >= 0)
|
|
||||||
close(driver_data->request_fds[i]);
|
|
||||||
|
|
||||||
close(driver_data->video_fd);
|
close(driver_data->video_fd);
|
||||||
close(driver_data->media_fd);
|
close(driver_data->media_fd);
|
||||||
|
|||||||
@@ -47,13 +47,8 @@ struct sunxi_cedrus_driver_data {
|
|||||||
struct object_heap surface_heap;
|
struct object_heap surface_heap;
|
||||||
struct object_heap buffer_heap;
|
struct object_heap buffer_heap;
|
||||||
struct object_heap image_heap;
|
struct object_heap image_heap;
|
||||||
char *luma_bufs[VIDEO_MAX_FRAME];
|
|
||||||
char *chroma_bufs[VIDEO_MAX_FRAME];
|
|
||||||
unsigned int num_dst_bufs;
|
|
||||||
int video_fd;
|
int video_fd;
|
||||||
int media_fd;
|
int media_fd;
|
||||||
int request_fds[INPUT_BUFFERS_NB];
|
|
||||||
int slice_offset[INPUT_BUFFERS_NB];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VAStatus VA_DRIVER_INIT_FUNC(VADriverContextP context);
|
VAStatus VA_DRIVER_INIT_FUNC(VADriverContextP context);
|
||||||
|
|||||||
+28
-16
@@ -50,9 +50,10 @@ VAStatus SunxiCedrusCreateSurfaces(VADriverContextP context, int width,
|
|||||||
struct object_surface *surface_object;
|
struct object_surface *surface_object;
|
||||||
unsigned int length[2];
|
unsigned int length[2];
|
||||||
unsigned int offset[2];
|
unsigned int offset[2];
|
||||||
|
void *destination_data[2];
|
||||||
VASurfaceID id;
|
VASurfaceID id;
|
||||||
|
unsigned int i, j;
|
||||||
int rc;
|
int rc;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (format != VA_RT_FORMAT_YUV420)
|
if (format != VA_RT_FORMAT_YUV420)
|
||||||
return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
|
return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
|
||||||
@@ -71,33 +72,37 @@ VAStatus SunxiCedrusCreateSurfaces(VADriverContextP context, int width,
|
|||||||
if (surface_object == NULL)
|
if (surface_object == NULL)
|
||||||
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
|
|
||||||
|
memset(surface_object, 0, sizeof(*surface_object));
|
||||||
|
|
||||||
surfaces_ids[i] = id;
|
surfaces_ids[i] = id;
|
||||||
|
|
||||||
rc = v4l2_request_buffer(driver_data->video_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, i, length, offset);
|
rc = v4l2_request_buffer(driver_data->video_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, i, length, offset);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
|
|
||||||
driver_data->luma_bufs[i] = mmap(NULL, length[0], PROT_READ | PROT_WRITE, MAP_SHARED,
|
destination_data[0] = mmap(NULL, length[0], PROT_READ | PROT_WRITE, MAP_SHARED, driver_data->video_fd, offset[0]);
|
||||||
driver_data->video_fd, offset[0]);
|
if (destination_data[0] == MAP_FAILED)
|
||||||
if (driver_data->luma_bufs[i] == MAP_FAILED)
|
|
||||||
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
|
|
||||||
driver_data->chroma_bufs[i] = mmap(NULL, length[1], PROT_READ | PROT_WRITE, MAP_SHARED,
|
destination_data[1] = mmap(NULL, length[1], PROT_READ | PROT_WRITE, MAP_SHARED, driver_data->video_fd, offset[1]);
|
||||||
driver_data->video_fd, offset[1]);
|
if (destination_data[1] == MAP_FAILED)
|
||||||
if (driver_data->chroma_bufs[i] == MAP_FAILED)
|
|
||||||
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
return VA_STATUS_ERROR_ALLOCATION_FAILED;
|
||||||
|
|
||||||
surface_object->status = VASurfaceReady;
|
surface_object->status = VASurfaceReady;
|
||||||
surface_object->width = width;
|
surface_object->width = width;
|
||||||
surface_object->height = height;
|
surface_object->height = height;
|
||||||
surface_object->input_buf_index = 0;
|
surface_object->destination_index = i;
|
||||||
surface_object->output_buf_index = i;
|
|
||||||
|
for (j = 0; j < 2; j++) {
|
||||||
|
surface_object->destination_data[j] = destination_data[j];
|
||||||
|
surface_object->destination_size[j] = length[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
surface_object->request_fd = -1;
|
||||||
|
|
||||||
surfaces_ids[i] = id;
|
surfaces_ids[i] = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
driver_data->num_dst_bufs = surfaces_count;
|
|
||||||
|
|
||||||
return VA_STATUS_SUCCESS;
|
return VA_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,13 +112,20 @@ VAStatus SunxiCedrusDestroySurfaces(VADriverContextP context,
|
|||||||
struct sunxi_cedrus_driver_data *driver_data =
|
struct sunxi_cedrus_driver_data *driver_data =
|
||||||
(struct sunxi_cedrus_driver_data *) context->pDriverData;
|
(struct sunxi_cedrus_driver_data *) context->pDriverData;
|
||||||
struct object_surface *surface_object;
|
struct object_surface *surface_object;
|
||||||
int i;
|
unsigned int i, j;
|
||||||
|
|
||||||
for (i = 0; i < surfaces_count; i++) {
|
for (i = 0; i < surfaces_count; i++) {
|
||||||
surface_object = (struct object_surface *) object_heap_lookup(&driver_data->surface_heap, surfaces_ids[i]);
|
surface_object = (struct object_surface *) object_heap_lookup(&driver_data->surface_heap, surfaces_ids[i]);
|
||||||
if (surface_object == NULL)
|
if (surface_object == NULL)
|
||||||
return VA_STATUS_ERROR_INVALID_SURFACE;
|
return VA_STATUS_ERROR_INVALID_SURFACE;
|
||||||
|
|
||||||
|
if (surface_object->source_data != NULL && surface_object->source_size > 0)
|
||||||
|
munmap(surface_object->source_data, surface_object->source_size);
|
||||||
|
|
||||||
|
for (j = 0; j < 2; j++)
|
||||||
|
if (surface_object->destination_data[j] != NULL && surface_object->destination_size[j] > 0)
|
||||||
|
munmap(surface_object->destination_data[j], surface_object->destination_size[j]);
|
||||||
|
|
||||||
object_heap_free(&driver_data->surface_heap, (struct object_base *) surface_object);
|
object_heap_free(&driver_data->surface_heap, (struct object_base *) surface_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +148,7 @@ VAStatus SunxiCedrusSyncSurface(VADriverContextP context,
|
|||||||
if (surface_object->status == VASurfaceSkipped)
|
if (surface_object->status == VASurfaceSkipped)
|
||||||
return VA_STATUS_ERROR_UNKNOWN;
|
return VA_STATUS_ERROR_UNKNOWN;
|
||||||
|
|
||||||
request_fd = driver_data->request_fds[surface_object->input_buf_index];
|
request_fd = surface_object->request_fd;
|
||||||
if (request_fd < 0)
|
if (request_fd < 0)
|
||||||
return VA_STATUS_ERROR_UNKNOWN;
|
return VA_STATUS_ERROR_UNKNOWN;
|
||||||
|
|
||||||
@@ -152,11 +164,11 @@ VAStatus SunxiCedrusSyncSurface(VADriverContextP context,
|
|||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return VA_STATUS_ERROR_OPERATION_FAILED;
|
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
rc = v4l2_dequeue_buffer(driver_data->video_fd, request_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, surface_object->input_buf_index);
|
rc = v4l2_dequeue_buffer(driver_data->video_fd, request_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, surface_object->source_index);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return VA_STATUS_ERROR_OPERATION_FAILED;
|
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
rc = v4l2_dequeue_buffer(driver_data->video_fd, request_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, surface_object->output_buf_index);
|
rc = v4l2_dequeue_buffer(driver_data->video_fd, request_fd, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, surface_object->destination_index);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return VA_STATUS_ERROR_OPERATION_FAILED;
|
return VA_STATUS_ERROR_OPERATION_FAILED;
|
||||||
|
|
||||||
@@ -220,7 +232,7 @@ VAStatus SunxiCedrusPutSurface(VADriverContextP context, VASurfaceID surface_id,
|
|||||||
|
|
||||||
for(x=dst_x; x < dst_x+dst_width; x++) {
|
for(x=dst_x; x < dst_x+dst_width; x++) {
|
||||||
for(y=dst_y; y < dst_y+dst_height; y++) {
|
for(y=dst_y; y < dst_y+dst_height; y++) {
|
||||||
char lum = driver_data->luma_bufs[surface_object->output_buf_index][x+src_width*y];
|
char lum = ((char *) surface_object->destination_data[0])[x+src_width*y];
|
||||||
xcolor.red = xcolor.green = xcolor.blue = lum*colorratio;
|
xcolor.red = xcolor.green = xcolor.blue = lum*colorratio;
|
||||||
XAllocColor(display, cm, &xcolor);
|
XAllocColor(display, cm, &xcolor);
|
||||||
XSetForeground(display, gc, xcolor.pixel);
|
XSetForeground(display, gc, xcolor.pixel);
|
||||||
|
|||||||
+12
-3
@@ -41,9 +41,18 @@ struct object_surface {
|
|||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
|
||||||
uint32_t request;
|
unsigned int source_index;
|
||||||
uint32_t input_buf_index;
|
void *source_data;
|
||||||
uint32_t output_buf_index;
|
unsigned int source_size;
|
||||||
|
|
||||||
|
unsigned int destination_index;
|
||||||
|
void *destination_data[2];
|
||||||
|
unsigned int destination_size[2];
|
||||||
|
|
||||||
|
struct v4l2_ctrl_mpeg2_frame_hdr mpeg2_header;
|
||||||
|
unsigned int slices_size;
|
||||||
|
|
||||||
|
int request_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
VAStatus SunxiCedrusCreateSurfaces(VADriverContextP context, int width,
|
VAStatus SunxiCedrusCreateSurfaces(VADriverContextP context, int width,
|
||||||
|
|||||||
Reference in New Issue
Block a user