vaapi.c
Go to the documentation of this file.
1 /*
2  * Video Acceleration API (video decoding)
3  * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1
4  *
5  * Copyright (C) 2008-2009 Splitted-Desktop Systems
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include "h264.h"
25 #include "vaapi_internal.h"
26 
27 /**
28  * @addtogroup VAAPI_Decoding
29  *
30  * @{
31  */
32 
33 static void destroy_buffers(VADisplay display, VABufferID *buffers, unsigned int n_buffers)
34 {
35  unsigned int i;
36  for (i = 0; i < n_buffers; i++) {
37  if (buffers[i]) {
38  vaDestroyBuffer(display, buffers[i]);
39  buffers[i] = 0;
40  }
41  }
42 }
43 
44 int ff_vaapi_render_picture(struct vaapi_context *vactx, VASurfaceID surface)
45 {
46  VABufferID va_buffers[3];
47  unsigned int n_va_buffers = 0;
48 
49  vaUnmapBuffer(vactx->display, vactx->pic_param_buf_id);
50  va_buffers[n_va_buffers++] = vactx->pic_param_buf_id;
51 
52  if (vactx->iq_matrix_buf_id) {
53  vaUnmapBuffer(vactx->display, vactx->iq_matrix_buf_id);
54  va_buffers[n_va_buffers++] = vactx->iq_matrix_buf_id;
55  }
56 
57  if (vactx->bitplane_buf_id) {
58  vaUnmapBuffer(vactx->display, vactx->bitplane_buf_id);
59  va_buffers[n_va_buffers++] = vactx->bitplane_buf_id;
60  }
61 
62  if (vaBeginPicture(vactx->display, vactx->context_id,
63  surface) != VA_STATUS_SUCCESS)
64  return -1;
65 
66  if (vaRenderPicture(vactx->display, vactx->context_id,
67  va_buffers, n_va_buffers) != VA_STATUS_SUCCESS)
68  return -1;
69 
70  if (vaRenderPicture(vactx->display, vactx->context_id,
71  vactx->slice_buf_ids,
72  vactx->n_slice_buf_ids) != VA_STATUS_SUCCESS)
73  return -1;
74 
75  if (vaEndPicture(vactx->display, vactx->context_id) != VA_STATUS_SUCCESS)
76  return -1;
77 
78  return 0;
79 }
80 
82 {
83  VABufferID *slice_buf_ids;
84  VABufferID slice_param_buf_id, slice_data_buf_id;
85 
86  if (vactx->slice_count == 0)
87  return 0;
88 
89  slice_buf_ids =
91  &vactx->slice_buf_ids_alloc,
92  (vactx->n_slice_buf_ids + 2) * sizeof(slice_buf_ids[0]));
93  if (!slice_buf_ids)
94  return -1;
95  vactx->slice_buf_ids = slice_buf_ids;
96 
97  slice_param_buf_id = 0;
98  if (vaCreateBuffer(vactx->display, vactx->context_id,
99  VASliceParameterBufferType,
100  vactx->slice_param_size,
101  vactx->slice_count, vactx->slice_params,
102  &slice_param_buf_id) != VA_STATUS_SUCCESS)
103  return -1;
104  vactx->slice_count = 0;
105 
106  slice_data_buf_id = 0;
107  if (vaCreateBuffer(vactx->display, vactx->context_id,
108  VASliceDataBufferType,
109  vactx->slice_data_size,
110  1, (void *)vactx->slice_data,
111  &slice_data_buf_id) != VA_STATUS_SUCCESS)
112  return -1;
113  vactx->slice_data = NULL;
114  vactx->slice_data_size = 0;
115 
116  slice_buf_ids[vactx->n_slice_buf_ids++] = slice_param_buf_id;
117  slice_buf_ids[vactx->n_slice_buf_ids++] = slice_data_buf_id;
118  return 0;
119 }
120 
121 static void *alloc_buffer(struct vaapi_context *vactx, int type, unsigned int size, uint32_t *buf_id)
122 {
123  void *data = NULL;
124 
125  *buf_id = 0;
126  if (vaCreateBuffer(vactx->display, vactx->context_id,
127  type, size, 1, NULL, buf_id) == VA_STATUS_SUCCESS)
128  vaMapBuffer(vactx->display, *buf_id, &data);
129 
130  return data;
131 }
132 
133 void *ff_vaapi_alloc_pic_param(struct vaapi_context *vactx, unsigned int size)
134 {
135  return alloc_buffer(vactx, VAPictureParameterBufferType, size, &vactx->pic_param_buf_id);
136 }
137 
138 void *ff_vaapi_alloc_iq_matrix(struct vaapi_context *vactx, unsigned int size)
139 {
140  return alloc_buffer(vactx, VAIQMatrixBufferType, size, &vactx->iq_matrix_buf_id);
141 }
142 
144 {
145  return alloc_buffer(vactx, VABitPlaneBufferType, size, &vactx->bitplane_buf_id);
146 }
147 
148 VASliceParameterBufferBase *ff_vaapi_alloc_slice(struct vaapi_context *vactx, const uint8_t *buffer, uint32_t size)
149 {
150  uint8_t *slice_params;
151  VASliceParameterBufferBase *slice_param;
152 
153  if (!vactx->slice_data)
154  vactx->slice_data = buffer;
155  if (vactx->slice_data + vactx->slice_data_size != buffer) {
156  if (ff_vaapi_commit_slices(vactx) < 0)
157  return NULL;
158  vactx->slice_data = buffer;
159  }
160 
161  slice_params =
163  &vactx->slice_params_alloc,
164  (vactx->slice_count + 1) * vactx->slice_param_size);
165  if (!slice_params)
166  return NULL;
167  vactx->slice_params = slice_params;
168 
169  slice_param = (VASliceParameterBufferBase *)(slice_params + vactx->slice_count * vactx->slice_param_size);
170  slice_param->slice_data_size = size;
171  slice_param->slice_data_offset = vactx->slice_data_size;
172  slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
173 
174  vactx->slice_count++;
175  vactx->slice_data_size += size;
176  return slice_param;
177 }
178 
180 {
181  struct vaapi_context * const vactx = avctx->hwaccel_context;
182 
183  av_dlog(avctx, "ff_vaapi_common_end_frame()\n");
184 
185  destroy_buffers(vactx->display, &vactx->pic_param_buf_id, 1);
186  destroy_buffers(vactx->display, &vactx->iq_matrix_buf_id, 1);
187  destroy_buffers(vactx->display, &vactx->bitplane_buf_id, 1);
188  destroy_buffers(vactx->display, vactx->slice_buf_ids, vactx->n_slice_buf_ids);
189  av_freep(&vactx->slice_buf_ids);
190  av_freep(&vactx->slice_params);
191  vactx->n_slice_buf_ids = 0;
192  vactx->slice_buf_ids_alloc = 0;
193  vactx->slice_count = 0;
194  vactx->slice_params_alloc = 0;
195 }
196 
198 {
199  struct vaapi_context * const vactx = avctx->hwaccel_context;
200  MpegEncContext *s = avctx->priv_data;
201  int ret;
202 
203  ret = ff_vaapi_commit_slices(vactx);
204  if (ret < 0)
205  goto finish;
206 
207  ret = ff_vaapi_render_picture(vactx,
209  if (ret < 0)
210  goto finish;
211 
213 
214 finish:
216  return ret;
217 }
218 
219 /* @} */
const uint8_t * slice_data
Pointer to slice data buffer base.
Definition: vaapi.h:160
const char * s
Definition: avisynth_c.h:668
uint32_t iq_matrix_buf_id
VAIQMatrixBuffer ID.
Definition: vaapi.h:89
uint32_t bitplane_buf_id
VABitPlaneBuffer ID (for VC-1 decoding)
Definition: vaapi.h:97
uint32_t context_id
Context ID (video decode pipeline)
Definition: vaapi.h:73
int ff_vaapi_render_picture(struct vaapi_context *vactx, VASurfaceID surface)
Definition: vaapi.c:44
av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (%s)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic?ac->func_descr_generic:ac->func_descr)
This structure is used to share data between the FFmpeg library and the client video application...
Definition: vaapi.h:50
unsigned int slice_params_alloc
Size of pre-allocated slice_params.
Definition: vaapi.h:145
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h)
Definition: mpegvideo.c:2996
uint8_t
void * hwaccel_context
Hardware accelerator context.
static void * alloc_buffer(struct vaapi_context *vactx, int type, unsigned int size, uint32_t *buf_id)
Definition: vaapi.c:121
uint32_t slice_data_size
Current size of slice data.
Definition: vaapi.h:168
H.264 / AVC / MPEG4 part10 codec.
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given block if it is not large enough, otherwise do nothing.
void ff_vaapi_common_end_frame(AVCodecContext *avctx)
Common AVHWAccel.end_frame() implementation.
Definition: vaapi.c:179
void * ff_vaapi_alloc_pic_param(struct vaapi_context *vactx, unsigned int size)
Allocate a new picture parameter buffer.
Definition: vaapi.c:133
static void destroy_buffers(VADisplay display, VABufferID *buffers, unsigned int n_buffers)
Definition: vaapi.c:33
Spectrum Plot time data
int size
ret
Definition: avfilter.c:821
Picture * current_picture_ptr
pointer to the current picture
Definition: mpegvideo.h:347
unsigned int slice_param_size
Size of a VASliceParameterBuffer element.
Definition: vaapi.h:137
void * display
Window system dependent data.
Definition: vaapi.h:57
NULL
Definition: eval.c:55
main external API structure.
VASliceParameterBufferBase * ff_vaapi_alloc_slice(struct vaapi_context *vactx, const uint8_t *buffer, uint32_t size)
Allocate a new slice descriptor for the input slice.
Definition: vaapi.c:148
uint32_t * slice_buf_ids
Slice parameter/data buffer IDs.
Definition: vaapi.h:105
synthesis window for stochastic i
unsigned int slice_count
Number of slices currently filled in.
Definition: vaapi.h:153
#define type
unsigned int slice_buf_ids_alloc
Size of pre-allocated slice_buf_ids.
Definition: vaapi.h:121
MpegEncContext.
Definition: mpegvideo.h:241
struct AVCodecContext * avctx
Definition: mpegvideo.h:243
int ff_vaapi_commit_slices(struct vaapi_context *vactx)
Definition: vaapi.c:81
int buffers
Definition: v4l2.c:113
void * ff_vaapi_alloc_iq_matrix(struct vaapi_context *vactx, unsigned int size)
Allocate a new IQ matrix buffer.
Definition: vaapi.c:138
the buffer and buffer reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFilterBuffer structures They must not be accessed but through references stored in AVFilterBufferRef structures Several references can point to the same buffer
static VASurfaceID ff_vaapi_get_surface_id(Picture *pic)
Extract VASurfaceID from a Picture.
unsigned int n_slice_buf_ids
Number of effective slice buffer IDs to send to the HW.
Definition: vaapi.h:113
void * slice_params
Pointer to VASliceParameterBuffers.
Definition: vaapi.h:129
uint8_t * ff_vaapi_alloc_bitplane(struct vaapi_context *vactx, uint32_t size)
Allocate a new bit-plane buffer.
Definition: vaapi.c:143
int ff_vaapi_mpeg_end_frame(AVCodecContext *avctx)
Definition: vaapi.c:197
uint32_t pic_param_buf_id
VAPictureParameterBuffer ID.
Definition: vaapi.h:81