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>
|
#include <linux/videodev2.h>
|
||||||
|
|
||||||
int mpeg2_fill_picture_parameters(struct sunxi_cedrus_driver_data *driver_data,
|
#include "v4l2.h"
|
||||||
struct object_context *context_object,
|
|
||||||
struct object_surface *surface_object,
|
int mpeg2_set_controls(struct sunxi_cedrus_driver_data *driver_data,
|
||||||
VAPictureParameterBufferMPEG2 *parameters)
|
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 *forward_reference_surface;
|
||||||
struct object_surface *backward_reference_surface;
|
struct object_surface *backward_reference_surface;
|
||||||
|
int rc;
|
||||||
|
|
||||||
slice_params->width = context_object->picture_width;
|
memset(&slice_params, 0, sizeof(slice_params));
|
||||||
slice_params->height = context_object->picture_height;
|
|
||||||
|
|
||||||
slice_params->slice_type = parameters->picture_coding_type;
|
slice_params.width = surface_object->width;
|
||||||
slice_params->f_code[0][0] = (parameters->f_code >> 12) & 0x0f;
|
slice_params.height = surface_object->height;
|
||||||
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.slice_pos = 0;
|
||||||
slice_params->picture_structure = parameters->picture_coding_extension.bits.picture_structure;
|
slice_params.slice_len = surface_object->slices_size * 8;
|
||||||
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.slice_type = parameters->picture_coding_type;
|
||||||
slice_params->concealment_motion_vectors = parameters->picture_coding_extension.bits.concealment_motion_vectors;
|
slice_params.f_code[0][0] = (parameters->f_code >> 12) & 0x0f;
|
||||||
slice_params->q_scale_type = parameters->picture_coding_extension.bits.q_scale_type;
|
slice_params.f_code[0][1] = (parameters->f_code >> 8) & 0x0f;
|
||||||
slice_params->intra_vlc_format = parameters->picture_coding_extension.bits.intra_vlc_format;
|
slice_params.f_code[1][0] = (parameters->f_code >> 4) & 0x0f;
|
||||||
slice_params->alternate_scan = parameters->picture_coding_extension.bits.alternate_scan;
|
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);
|
forward_reference_surface = SURFACE(parameters->forward_reference_picture);
|
||||||
if (forward_reference_surface != NULL)
|
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
|
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);
|
backward_reference_surface = SURFACE(parameters->backward_reference_picture);
|
||||||
if (backward_reference_surface != NULL)
|
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
|
else
|
||||||
slice_params->backward_ref_index = surface_object->destination_index;
|
slice_params.backward_ref_index = surface_object->destination_index;
|
||||||
|
|
||||||
return 0;
|
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;
|
||||||
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;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-7
@@ -33,12 +33,7 @@
|
|||||||
|
|
||||||
#include "surface.h"
|
#include "surface.h"
|
||||||
|
|
||||||
int mpeg2_fill_picture_parameters(struct sunxi_cedrus_driver_data *driver_data,
|
int mpeg2_set_controls(struct sunxi_cedrus_driver_data *driver_data,
|
||||||
struct object_context *context_object,
|
struct object_surface *surface_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);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+60
-46
@@ -45,6 +45,60 @@
|
|||||||
#include "media.h"
|
#include "media.h"
|
||||||
#include "utils.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,
|
VAStatus SunxiCedrusBeginPicture(VADriverContextP context,
|
||||||
VAContextID context_id, VASurfaceID surface_id)
|
VAContextID context_id, VASurfaceID surface_id)
|
||||||
{
|
{
|
||||||
@@ -79,9 +133,6 @@ VAStatus SunxiCedrusRenderPicture(VADriverContextP context,
|
|||||||
struct object_config *config_object;
|
struct object_config *config_object;
|
||||||
struct object_surface *surface_object;
|
struct object_surface *surface_object;
|
||||||
struct object_buffer *buffer_object;
|
struct object_buffer *buffer_object;
|
||||||
VAPictureParameterBufferMPEG2 *mpeg2_parameters;
|
|
||||||
void *data;
|
|
||||||
unsigned int size;
|
|
||||||
int rc;
|
int rc;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -102,28 +153,9 @@ VAStatus SunxiCedrusRenderPicture(VADriverContextP context,
|
|||||||
if (buffer_object == NULL)
|
if (buffer_object == NULL)
|
||||||
return VA_STATUS_ERROR_INVALID_BUFFER;
|
return VA_STATUS_ERROR_INVALID_BUFFER;
|
||||||
|
|
||||||
switch (config_object->profile) {
|
rc = codec_store_buffer(driver_data, config_object->profile, surface_object, buffer_object);
|
||||||
case VAProfileMPEG2Simple:
|
if (rc != VA_STATUS_SUCCESS)
|
||||||
case VAProfileMPEG2Main:
|
return rc;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return VA_STATUS_SUCCESS;
|
return VA_STATUS_SUCCESS;
|
||||||
@@ -137,9 +169,6 @@ VAStatus SunxiCedrusEndPicture(VADriverContextP context,
|
|||||||
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;
|
||||||
void *control_data;
|
|
||||||
unsigned int control_size;
|
|
||||||
unsigned int control_id;
|
|
||||||
int request_fd;
|
int request_fd;
|
||||||
VAStatus status;
|
VAStatus status;
|
||||||
int rc;
|
int rc;
|
||||||
@@ -165,24 +194,9 @@ VAStatus SunxiCedrusEndPicture(VADriverContextP context,
|
|||||||
surface_object->request_fd = request_fd;
|
surface_object->request_fd = request_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (config_object->profile) {
|
rc = codec_set_controls(driver_data, config_object->profile, surface_object);
|
||||||
case VAProfileMPEG2Simple:
|
if (rc != VA_STATUS_SUCCESS)
|
||||||
case VAProfileMPEG2Main:
|
return rc;
|
||||||
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 = v4l2_queue_buffer(driver_data->video_fd, -1, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, surface_object->destination_index, 0, surface_object->destination_buffers_count);
|
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)
|
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_planes_count = destination_planes_count;
|
||||||
surface_object->destination_buffers_count = video_format->v4l2_buffers_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->slices_size = 0;
|
||||||
|
|
||||||
surface_object->request_fd = -1;
|
surface_object->request_fd = -1;
|
||||||
|
|||||||
+6
-1
@@ -57,9 +57,14 @@ struct object_surface {
|
|||||||
unsigned int destination_planes_count;
|
unsigned int destination_planes_count;
|
||||||
unsigned int destination_buffers_count;
|
unsigned int destination_buffers_count;
|
||||||
|
|
||||||
struct v4l2_ctrl_mpeg2_slice_params mpeg2_slice_params;
|
|
||||||
unsigned int slices_size;
|
unsigned int slices_size;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
VAPictureParameterBufferMPEG2 picture;
|
||||||
|
} mpeg2;
|
||||||
|
} params;
|
||||||
|
|
||||||
int request_fd;
|
int request_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user