annotate ffmpeg/libavcodec/vaapi.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * Video Acceleration API (video decoding)
yading@10 3 * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1
yading@10 4 *
yading@10 5 * Copyright (C) 2008-2009 Splitted-Desktop Systems
yading@10 6 *
yading@10 7 * This file is part of FFmpeg.
yading@10 8 *
yading@10 9 * FFmpeg is free software; you can redistribute it and/or
yading@10 10 * modify it under the terms of the GNU Lesser General Public
yading@10 11 * License as published by the Free Software Foundation; either
yading@10 12 * version 2.1 of the License, or (at your option) any later version.
yading@10 13 *
yading@10 14 * FFmpeg is distributed in the hope that it will be useful,
yading@10 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 17 * Lesser General Public License for more details.
yading@10 18 *
yading@10 19 * You should have received a copy of the GNU Lesser General Public
yading@10 20 * License along with FFmpeg; if not, write to the Free Software
yading@10 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 22 */
yading@10 23
yading@10 24 #include "h264.h"
yading@10 25 #include "vaapi_internal.h"
yading@10 26
yading@10 27 /**
yading@10 28 * @addtogroup VAAPI_Decoding
yading@10 29 *
yading@10 30 * @{
yading@10 31 */
yading@10 32
yading@10 33 static void destroy_buffers(VADisplay display, VABufferID *buffers, unsigned int n_buffers)
yading@10 34 {
yading@10 35 unsigned int i;
yading@10 36 for (i = 0; i < n_buffers; i++) {
yading@10 37 if (buffers[i]) {
yading@10 38 vaDestroyBuffer(display, buffers[i]);
yading@10 39 buffers[i] = 0;
yading@10 40 }
yading@10 41 }
yading@10 42 }
yading@10 43
yading@10 44 int ff_vaapi_render_picture(struct vaapi_context *vactx, VASurfaceID surface)
yading@10 45 {
yading@10 46 VABufferID va_buffers[3];
yading@10 47 unsigned int n_va_buffers = 0;
yading@10 48
yading@10 49 vaUnmapBuffer(vactx->display, vactx->pic_param_buf_id);
yading@10 50 va_buffers[n_va_buffers++] = vactx->pic_param_buf_id;
yading@10 51
yading@10 52 if (vactx->iq_matrix_buf_id) {
yading@10 53 vaUnmapBuffer(vactx->display, vactx->iq_matrix_buf_id);
yading@10 54 va_buffers[n_va_buffers++] = vactx->iq_matrix_buf_id;
yading@10 55 }
yading@10 56
yading@10 57 if (vactx->bitplane_buf_id) {
yading@10 58 vaUnmapBuffer(vactx->display, vactx->bitplane_buf_id);
yading@10 59 va_buffers[n_va_buffers++] = vactx->bitplane_buf_id;
yading@10 60 }
yading@10 61
yading@10 62 if (vaBeginPicture(vactx->display, vactx->context_id,
yading@10 63 surface) != VA_STATUS_SUCCESS)
yading@10 64 return -1;
yading@10 65
yading@10 66 if (vaRenderPicture(vactx->display, vactx->context_id,
yading@10 67 va_buffers, n_va_buffers) != VA_STATUS_SUCCESS)
yading@10 68 return -1;
yading@10 69
yading@10 70 if (vaRenderPicture(vactx->display, vactx->context_id,
yading@10 71 vactx->slice_buf_ids,
yading@10 72 vactx->n_slice_buf_ids) != VA_STATUS_SUCCESS)
yading@10 73 return -1;
yading@10 74
yading@10 75 if (vaEndPicture(vactx->display, vactx->context_id) != VA_STATUS_SUCCESS)
yading@10 76 return -1;
yading@10 77
yading@10 78 return 0;
yading@10 79 }
yading@10 80
yading@10 81 int ff_vaapi_commit_slices(struct vaapi_context *vactx)
yading@10 82 {
yading@10 83 VABufferID *slice_buf_ids;
yading@10 84 VABufferID slice_param_buf_id, slice_data_buf_id;
yading@10 85
yading@10 86 if (vactx->slice_count == 0)
yading@10 87 return 0;
yading@10 88
yading@10 89 slice_buf_ids =
yading@10 90 av_fast_realloc(vactx->slice_buf_ids,
yading@10 91 &vactx->slice_buf_ids_alloc,
yading@10 92 (vactx->n_slice_buf_ids + 2) * sizeof(slice_buf_ids[0]));
yading@10 93 if (!slice_buf_ids)
yading@10 94 return -1;
yading@10 95 vactx->slice_buf_ids = slice_buf_ids;
yading@10 96
yading@10 97 slice_param_buf_id = 0;
yading@10 98 if (vaCreateBuffer(vactx->display, vactx->context_id,
yading@10 99 VASliceParameterBufferType,
yading@10 100 vactx->slice_param_size,
yading@10 101 vactx->slice_count, vactx->slice_params,
yading@10 102 &slice_param_buf_id) != VA_STATUS_SUCCESS)
yading@10 103 return -1;
yading@10 104 vactx->slice_count = 0;
yading@10 105
yading@10 106 slice_data_buf_id = 0;
yading@10 107 if (vaCreateBuffer(vactx->display, vactx->context_id,
yading@10 108 VASliceDataBufferType,
yading@10 109 vactx->slice_data_size,
yading@10 110 1, (void *)vactx->slice_data,
yading@10 111 &slice_data_buf_id) != VA_STATUS_SUCCESS)
yading@10 112 return -1;
yading@10 113 vactx->slice_data = NULL;
yading@10 114 vactx->slice_data_size = 0;
yading@10 115
yading@10 116 slice_buf_ids[vactx->n_slice_buf_ids++] = slice_param_buf_id;
yading@10 117 slice_buf_ids[vactx->n_slice_buf_ids++] = slice_data_buf_id;
yading@10 118 return 0;
yading@10 119 }
yading@10 120
yading@10 121 static void *alloc_buffer(struct vaapi_context *vactx, int type, unsigned int size, uint32_t *buf_id)
yading@10 122 {
yading@10 123 void *data = NULL;
yading@10 124
yading@10 125 *buf_id = 0;
yading@10 126 if (vaCreateBuffer(vactx->display, vactx->context_id,
yading@10 127 type, size, 1, NULL, buf_id) == VA_STATUS_SUCCESS)
yading@10 128 vaMapBuffer(vactx->display, *buf_id, &data);
yading@10 129
yading@10 130 return data;
yading@10 131 }
yading@10 132
yading@10 133 void *ff_vaapi_alloc_pic_param(struct vaapi_context *vactx, unsigned int size)
yading@10 134 {
yading@10 135 return alloc_buffer(vactx, VAPictureParameterBufferType, size, &vactx->pic_param_buf_id);
yading@10 136 }
yading@10 137
yading@10 138 void *ff_vaapi_alloc_iq_matrix(struct vaapi_context *vactx, unsigned int size)
yading@10 139 {
yading@10 140 return alloc_buffer(vactx, VAIQMatrixBufferType, size, &vactx->iq_matrix_buf_id);
yading@10 141 }
yading@10 142
yading@10 143 uint8_t *ff_vaapi_alloc_bitplane(struct vaapi_context *vactx, uint32_t size)
yading@10 144 {
yading@10 145 return alloc_buffer(vactx, VABitPlaneBufferType, size, &vactx->bitplane_buf_id);
yading@10 146 }
yading@10 147
yading@10 148 VASliceParameterBufferBase *ff_vaapi_alloc_slice(struct vaapi_context *vactx, const uint8_t *buffer, uint32_t size)
yading@10 149 {
yading@10 150 uint8_t *slice_params;
yading@10 151 VASliceParameterBufferBase *slice_param;
yading@10 152
yading@10 153 if (!vactx->slice_data)
yading@10 154 vactx->slice_data = buffer;
yading@10 155 if (vactx->slice_data + vactx->slice_data_size != buffer) {
yading@10 156 if (ff_vaapi_commit_slices(vactx) < 0)
yading@10 157 return NULL;
yading@10 158 vactx->slice_data = buffer;
yading@10 159 }
yading@10 160
yading@10 161 slice_params =
yading@10 162 av_fast_realloc(vactx->slice_params,
yading@10 163 &vactx->slice_params_alloc,
yading@10 164 (vactx->slice_count + 1) * vactx->slice_param_size);
yading@10 165 if (!slice_params)
yading@10 166 return NULL;
yading@10 167 vactx->slice_params = slice_params;
yading@10 168
yading@10 169 slice_param = (VASliceParameterBufferBase *)(slice_params + vactx->slice_count * vactx->slice_param_size);
yading@10 170 slice_param->slice_data_size = size;
yading@10 171 slice_param->slice_data_offset = vactx->slice_data_size;
yading@10 172 slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
yading@10 173
yading@10 174 vactx->slice_count++;
yading@10 175 vactx->slice_data_size += size;
yading@10 176 return slice_param;
yading@10 177 }
yading@10 178
yading@10 179 void ff_vaapi_common_end_frame(AVCodecContext *avctx)
yading@10 180 {
yading@10 181 struct vaapi_context * const vactx = avctx->hwaccel_context;
yading@10 182
yading@10 183 av_dlog(avctx, "ff_vaapi_common_end_frame()\n");
yading@10 184
yading@10 185 destroy_buffers(vactx->display, &vactx->pic_param_buf_id, 1);
yading@10 186 destroy_buffers(vactx->display, &vactx->iq_matrix_buf_id, 1);
yading@10 187 destroy_buffers(vactx->display, &vactx->bitplane_buf_id, 1);
yading@10 188 destroy_buffers(vactx->display, vactx->slice_buf_ids, vactx->n_slice_buf_ids);
yading@10 189 av_freep(&vactx->slice_buf_ids);
yading@10 190 av_freep(&vactx->slice_params);
yading@10 191 vactx->n_slice_buf_ids = 0;
yading@10 192 vactx->slice_buf_ids_alloc = 0;
yading@10 193 vactx->slice_count = 0;
yading@10 194 vactx->slice_params_alloc = 0;
yading@10 195 }
yading@10 196
yading@10 197 int ff_vaapi_mpeg_end_frame(AVCodecContext *avctx)
yading@10 198 {
yading@10 199 struct vaapi_context * const vactx = avctx->hwaccel_context;
yading@10 200 MpegEncContext *s = avctx->priv_data;
yading@10 201 int ret;
yading@10 202
yading@10 203 ret = ff_vaapi_commit_slices(vactx);
yading@10 204 if (ret < 0)
yading@10 205 goto finish;
yading@10 206
yading@10 207 ret = ff_vaapi_render_picture(vactx,
yading@10 208 ff_vaapi_get_surface_id(s->current_picture_ptr));
yading@10 209 if (ret < 0)
yading@10 210 goto finish;
yading@10 211
yading@10 212 ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);
yading@10 213
yading@10 214 finish:
yading@10 215 ff_vaapi_common_end_frame(avctx);
yading@10 216 return ret;
yading@10 217 }
yading@10 218
yading@10 219 /* @} */