Abstract away MPEG2 support

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
This commit is contained in:
Maxime Ripard
2018-07-11 16:18:18 +02:00
committed by Paul Kocialkowski
parent 03fd51b3b3
commit d7d8fc744b
5 changed files with 104 additions and 98 deletions
+35 -43
View File
@@ -34,63 +34,55 @@
#include <linux/videodev2.h>
int mpeg2_fill_picture_parameters(struct sunxi_cedrus_driver_data *driver_data,
struct object_context *context_object,
struct object_surface *surface_object,
VAPictureParameterBufferMPEG2 *parameters)
#include "v4l2.h"
int mpeg2_set_controls(struct sunxi_cedrus_driver_data *driver_data,
struct object_surface *surface_object)
{
struct v4l2_ctrl_mpeg2_slice_params *slice_params = &surface_object->mpeg2_slice_params;
VAPictureParameterBufferMPEG2 *parameters = &surface_object->params.mpeg2.picture;
struct v4l2_ctrl_mpeg2_slice_params slice_params;
struct object_surface *forward_reference_surface;
struct object_surface *backward_reference_surface;
int rc;
slice_params->width = context_object->picture_width;
slice_params->height = context_object->picture_height;
memset(&slice_params, 0, sizeof(slice_params));
slice_params->slice_type = parameters->picture_coding_type;
slice_params->f_code[0][0] = (parameters->f_code >> 12) & 0x0f;
slice_params->f_code[0][1] = (parameters->f_code >> 8) & 0x0f;
slice_params->f_code[1][0] = (parameters->f_code >> 4) & 0x0f;
slice_params->f_code[1][1] = (parameters->f_code >> 0) & 0x0f;
slice_params.width = surface_object->width;
slice_params.height = surface_object->height;
slice_params->intra_dc_precision = parameters->picture_coding_extension.bits.intra_dc_precision;
slice_params->picture_structure = parameters->picture_coding_extension.bits.picture_structure;
slice_params->top_field_first = parameters->picture_coding_extension.bits.top_field_first;
slice_params->frame_pred_frame_dct = parameters->picture_coding_extension.bits.frame_pred_frame_dct;
slice_params->concealment_motion_vectors = parameters->picture_coding_extension.bits.concealment_motion_vectors;
slice_params->q_scale_type = parameters->picture_coding_extension.bits.q_scale_type;
slice_params->intra_vlc_format = parameters->picture_coding_extension.bits.intra_vlc_format;
slice_params->alternate_scan = parameters->picture_coding_extension.bits.alternate_scan;
slice_params.slice_pos = 0;
slice_params.slice_len = surface_object->slices_size * 8;
slice_params.slice_type = parameters->picture_coding_type;
slice_params.f_code[0][0] = (parameters->f_code >> 12) & 0x0f;
slice_params.f_code[0][1] = (parameters->f_code >> 8) & 0x0f;
slice_params.f_code[1][0] = (parameters->f_code >> 4) & 0x0f;
slice_params.f_code[1][1] = (parameters->f_code >> 0) & 0x0f;
slice_params.intra_dc_precision = parameters->picture_coding_extension.bits.intra_dc_precision;
slice_params.picture_structure = parameters->picture_coding_extension.bits.picture_structure;
slice_params.top_field_first = parameters->picture_coding_extension.bits.top_field_first;
slice_params.frame_pred_frame_dct = parameters->picture_coding_extension.bits.frame_pred_frame_dct;
slice_params.concealment_motion_vectors = parameters->picture_coding_extension.bits.concealment_motion_vectors;
slice_params.q_scale_type = parameters->picture_coding_extension.bits.q_scale_type;
slice_params.intra_vlc_format = parameters->picture_coding_extension.bits.intra_vlc_format;
slice_params.alternate_scan = parameters->picture_coding_extension.bits.alternate_scan;
forward_reference_surface = SURFACE(parameters->forward_reference_picture);
if (forward_reference_surface != NULL)
slice_params->forward_ref_index = forward_reference_surface->destination_index;
slice_params.forward_ref_index = forward_reference_surface->destination_index;
else
slice_params->forward_ref_index = surface_object->destination_index;
slice_params.forward_ref_index = surface_object->destination_index;
backward_reference_surface = SURFACE(parameters->backward_reference_picture);
if (backward_reference_surface != NULL)
slice_params->backward_ref_index = backward_reference_surface->destination_index;
slice_params.backward_ref_index = backward_reference_surface->destination_index;
else
slice_params->backward_ref_index = surface_object->destination_index;
return 0;
}
int mpeg2_fill_slice_data(struct sunxi_cedrus_driver_data *driver_data,
struct object_context *context_object,
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;
slice_params.backward_ref_index = surface_object->destination_index;
rc = v4l2_set_control(driver_data->video_fd, surface_object->request_fd, V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS, &slice_params, sizeof(slice_params));
if (rc < 0)
return VA_STATUS_ERROR_OPERATION_FAILED;
return 0;
}
+2 -7
View File
@@ -33,12 +33,7 @@
#include "surface.h"
int mpeg2_fill_picture_parameters(struct sunxi_cedrus_driver_data *driver_data,
struct object_context *context_object,
struct object_surface *surface_object,
VAPictureParameterBufferMPEG2 *parameters);
int mpeg2_fill_slice_data(struct sunxi_cedrus_driver_data *driver_data,
struct object_context *context_object,
struct object_surface *surface_object, void *data, unsigned int size);
int mpeg2_set_controls(struct sunxi_cedrus_driver_data *driver_data,
struct object_surface *surface_object);
#endif
+60 -46
View File
@@ -45,6 +45,60 @@
#include "media.h"
#include "utils.h"
static VAStatus codec_store_buffer(struct sunxi_cedrus_driver_data *driver_data,
VAProfile profile, struct object_surface *surface_object,
struct object_buffer *buffer_object)
{
switch (buffer_object->type) {
case VASliceDataBufferType:
/*
* 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(surface_object->source_data + surface_object->slices_size, buffer_object->data, buffer_object->size * buffer_object->count);
surface_object->slices_size += buffer_object->size * buffer_object->count;
break;
case VAPictureParameterBufferType:
switch (profile) {
case VAProfileMPEG2Simple:
case VAProfileMPEG2Main:
memcpy(&surface_object->params.mpeg2.picture, buffer_object->data, sizeof(surface_object->params.mpeg2.picture));
break;
default:
break;
}
break;
default:
break;
}
return VA_STATUS_SUCCESS;
}
static VAStatus codec_set_controls(struct sunxi_cedrus_driver_data *driver_data,
VAProfile profile, struct object_surface *surface_object)
{
int rc;
switch (profile) {
case VAProfileMPEG2Simple:
case VAProfileMPEG2Main:
rc = mpeg2_set_controls(driver_data, surface_object);
if (rc < 0)
return VA_STATUS_ERROR_OPERATION_FAILED;
break;
default:
return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
}
return VA_STATUS_SUCCESS;
}
VAStatus SunxiCedrusBeginPicture(VADriverContextP context,
VAContextID context_id, VASurfaceID surface_id)
{
@@ -79,9 +133,6 @@ VAStatus SunxiCedrusRenderPicture(VADriverContextP context,
struct object_config *config_object;
struct object_surface *surface_object;
struct object_buffer *buffer_object;
VAPictureParameterBufferMPEG2 *mpeg2_parameters;
void *data;
unsigned int size;
int rc;
int i;
@@ -102,28 +153,9 @@ VAStatus SunxiCedrusRenderPicture(VADriverContextP context,
if (buffer_object == NULL)
return VA_STATUS_ERROR_INVALID_BUFFER;
switch (config_object->profile) {
case VAProfileMPEG2Simple:
case VAProfileMPEG2Main:
if (buffer_object->type == VASliceDataBufferType) {
data = buffer_object->data;
size = buffer_object->size * buffer_object->count;
rc = mpeg2_fill_slice_data(driver_data, context_object, surface_object, data, size);
if (rc < 0)
return VA_STATUS_ERROR_OPERATION_FAILED;
} else if (buffer_object->type == VAPictureParameterBufferType) {
mpeg2_parameters = (VAPictureParameterBufferMPEG2 *) buffer_object->data;
rc = mpeg2_fill_picture_parameters(driver_data, context_object, surface_object, mpeg2_parameters);
if (rc < 0)
return VA_STATUS_ERROR_OPERATION_FAILED;
}
break;
default:
break;
}
rc = codec_store_buffer(driver_data, config_object->profile, surface_object, buffer_object);
if (rc != VA_STATUS_SUCCESS)
return rc;
}
return VA_STATUS_SUCCESS;
@@ -137,9 +169,6 @@ VAStatus SunxiCedrusEndPicture(VADriverContextP context,
struct object_context *context_object;
struct object_config *config_object;
struct object_surface *surface_object;
void *control_data;
unsigned int control_size;
unsigned int control_id;
int request_fd;
VAStatus status;
int rc;
@@ -165,24 +194,9 @@ VAStatus SunxiCedrusEndPicture(VADriverContextP context,
surface_object->request_fd = request_fd;
}
switch (config_object->profile) {
case VAProfileMPEG2Simple:
case VAProfileMPEG2Main:
surface_object->mpeg2_slice_params.slice_pos = 0;
surface_object->mpeg2_slice_params.slice_len = surface_object->slices_size * 8;
control_id = V4L2_CID_MPEG_VIDEO_MPEG2_SLICE_PARAMS;
control_data = &surface_object->mpeg2_slice_params;
control_size = sizeof(surface_object->mpeg2_slice_params);
break;
default:
return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
}
rc = v4l2_set_control(driver_data->video_fd, request_fd, control_id, control_data, control_size);
if (rc < 0)
return VA_STATUS_ERROR_OPERATION_FAILED;
rc = codec_set_controls(driver_data, config_object->profile, surface_object);
if (rc != VA_STATUS_SUCCESS)
return rc;
rc = v4l2_queue_buffer(driver_data->video_fd, -1, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, surface_object->destination_index, 0, surface_object->destination_buffers_count);
if (rc < 0)
+1 -1
View File
@@ -129,7 +129,7 @@ VAStatus SunxiCedrusCreateSurfaces(VADriverContextP context, int width,
surface_object->destination_planes_count = destination_planes_count;
surface_object->destination_buffers_count = video_format->v4l2_buffers_count;
memset(&surface_object->mpeg2_slice_params, 0, sizeof(surface_object->mpeg2_slice_params));
memset(&surface_object->params, 0, sizeof(surface_object->params));
surface_object->slices_size = 0;
surface_object->request_fd = -1;
+6 -1
View File
@@ -57,9 +57,14 @@ struct object_surface {
unsigned int destination_planes_count;
unsigned int destination_buffers_count;
struct v4l2_ctrl_mpeg2_slice_params mpeg2_slice_params;
unsigned int slices_size;
union {
struct {
VAPictureParameterBufferMPEG2 picture;
} mpeg2;
} params;
int request_fd;
};