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:
committed by
Paul Kocialkowski
parent
03fd51b3b3
commit
d7d8fc744b
+35
-43
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user