00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "vaapi_internal.h"
00025
00032 static void destroy_buffers(VADisplay display, VABufferID *buffers, unsigned int n_buffers)
00033 {
00034 unsigned int i;
00035 for (i = 0; i < n_buffers; i++) {
00036 if (buffers[i]) {
00037 vaDestroyBuffer(display, buffers[i]);
00038 buffers[i] = 0;
00039 }
00040 }
00041 }
00042
00043 static int render_picture(struct vaapi_context *vactx, VASurfaceID surface)
00044 {
00045 VABufferID va_buffers[3];
00046 unsigned int n_va_buffers = 0;
00047
00048 vaUnmapBuffer(vactx->display, vactx->pic_param_buf_id);
00049 va_buffers[n_va_buffers++] = vactx->pic_param_buf_id;
00050
00051 if (vactx->iq_matrix_buf_id) {
00052 vaUnmapBuffer(vactx->display, vactx->iq_matrix_buf_id);
00053 va_buffers[n_va_buffers++] = vactx->iq_matrix_buf_id;
00054 }
00055
00056 if (vactx->bitplane_buf_id) {
00057 vaUnmapBuffer(vactx->display, vactx->bitplane_buf_id);
00058 va_buffers[n_va_buffers++] = vactx->bitplane_buf_id;
00059 }
00060
00061 if (vaBeginPicture(vactx->display, vactx->context_id,
00062 surface) != VA_STATUS_SUCCESS)
00063 return -1;
00064
00065 if (vaRenderPicture(vactx->display, vactx->context_id,
00066 va_buffers, n_va_buffers) != VA_STATUS_SUCCESS)
00067 return -1;
00068
00069 if (vaRenderPicture(vactx->display, vactx->context_id,
00070 vactx->slice_buf_ids,
00071 vactx->n_slice_buf_ids) != VA_STATUS_SUCCESS)
00072 return -1;
00073
00074 if (vaEndPicture(vactx->display, vactx->context_id) != VA_STATUS_SUCCESS)
00075 return -1;
00076
00077 return 0;
00078 }
00079
00080 static int commit_slices(struct vaapi_context *vactx)
00081 {
00082 VABufferID *slice_buf_ids;
00083 VABufferID slice_param_buf_id, slice_data_buf_id;
00084
00085 if (vactx->slice_count == 0)
00086 return 0;
00087
00088 slice_buf_ids =
00089 av_fast_realloc(vactx->slice_buf_ids,
00090 &vactx->slice_buf_ids_alloc,
00091 (vactx->n_slice_buf_ids + 2) * sizeof(slice_buf_ids[0]));
00092 if (!slice_buf_ids)
00093 return -1;
00094 vactx->slice_buf_ids = slice_buf_ids;
00095
00096 slice_param_buf_id = 0;
00097 if (vaCreateBuffer(vactx->display, vactx->context_id,
00098 VASliceParameterBufferType,
00099 vactx->slice_param_size,
00100 vactx->slice_count, vactx->slice_params,
00101 &slice_param_buf_id) != VA_STATUS_SUCCESS)
00102 return -1;
00103 vactx->slice_count = 0;
00104
00105 slice_data_buf_id = 0;
00106 if (vaCreateBuffer(vactx->display, vactx->context_id,
00107 VASliceDataBufferType,
00108 vactx->slice_data_size,
00109 1, (void *)vactx->slice_data,
00110 &slice_data_buf_id) != VA_STATUS_SUCCESS)
00111 return -1;
00112 vactx->slice_data = NULL;
00113 vactx->slice_data_size = 0;
00114
00115 slice_buf_ids[vactx->n_slice_buf_ids++] = slice_param_buf_id;
00116 slice_buf_ids[vactx->n_slice_buf_ids++] = slice_data_buf_id;
00117 return 0;
00118 }
00119
00120 static void *alloc_buffer(struct vaapi_context *vactx, int type, unsigned int size, uint32_t *buf_id)
00121 {
00122 void *data = NULL;
00123
00124 *buf_id = 0;
00125 if (vaCreateBuffer(vactx->display, vactx->context_id,
00126 type, size, 1, NULL, buf_id) == VA_STATUS_SUCCESS)
00127 vaMapBuffer(vactx->display, *buf_id, &data);
00128
00129 return data;
00130 }
00131
00132 void *ff_vaapi_alloc_pic_param(struct vaapi_context *vactx, unsigned int size)
00133 {
00134 return alloc_buffer(vactx, VAPictureParameterBufferType, size, &vactx->pic_param_buf_id);
00135 }
00136
00137 void *ff_vaapi_alloc_iq_matrix(struct vaapi_context *vactx, unsigned int size)
00138 {
00139 return alloc_buffer(vactx, VAIQMatrixBufferType, size, &vactx->iq_matrix_buf_id);
00140 }
00141
00142 uint8_t *ff_vaapi_alloc_bitplane(struct vaapi_context *vactx, uint32_t size)
00143 {
00144 return alloc_buffer(vactx, VABitPlaneBufferType, size, &vactx->bitplane_buf_id);
00145 }
00146
00147 VASliceParameterBufferBase *ff_vaapi_alloc_slice(struct vaapi_context *vactx, const uint8_t *buffer, uint32_t size)
00148 {
00149 uint8_t *slice_params;
00150 VASliceParameterBufferBase *slice_param;
00151
00152 if (!vactx->slice_data)
00153 vactx->slice_data = buffer;
00154 if (vactx->slice_data + vactx->slice_data_size != buffer) {
00155 if (commit_slices(vactx) < 0)
00156 return NULL;
00157 vactx->slice_data = buffer;
00158 }
00159
00160 slice_params =
00161 av_fast_realloc(vactx->slice_params,
00162 &vactx->slice_params_alloc,
00163 (vactx->slice_count + 1) * vactx->slice_param_size);
00164 if (!slice_params)
00165 return NULL;
00166 vactx->slice_params = slice_params;
00167
00168 slice_param = (VASliceParameterBufferBase *)(slice_params + vactx->slice_count * vactx->slice_param_size);
00169 slice_param->slice_data_size = size;
00170 slice_param->slice_data_offset = vactx->slice_data_size;
00171 slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
00172
00173 vactx->slice_count++;
00174 vactx->slice_data_size += size;
00175 return slice_param;
00176 }
00177
00178 int ff_vaapi_common_end_frame(MpegEncContext *s)
00179 {
00180 struct vaapi_context * const vactx = s->avctx->hwaccel_context;
00181 int ret = -1;
00182
00183 av_dlog(s->avctx, "ff_vaapi_common_end_frame()\n");
00184
00185 if (commit_slices(vactx) < 0)
00186 goto done;
00187 if (vactx->n_slice_buf_ids > 0) {
00188 if (render_picture(vactx, ff_vaapi_get_surface_id(s->current_picture_ptr)) < 0)
00189 goto done;
00190 ff_draw_horiz_band(s, 0, s->avctx->height);
00191 }
00192 ret = 0;
00193
00194 done:
00195 destroy_buffers(vactx->display, &vactx->pic_param_buf_id, 1);
00196 destroy_buffers(vactx->display, &vactx->iq_matrix_buf_id, 1);
00197 destroy_buffers(vactx->display, &vactx->bitplane_buf_id, 1);
00198 destroy_buffers(vactx->display, vactx->slice_buf_ids, vactx->n_slice_buf_ids);
00199 av_freep(&vactx->slice_buf_ids);
00200 av_freep(&vactx->slice_params);
00201 vactx->n_slice_buf_ids = 0;
00202 vactx->slice_buf_ids_alloc = 0;
00203 vactx->slice_count = 0;
00204 vactx->slice_params_alloc = 0;
00205 return ret;
00206 }
00207
00208