• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/vaapi.c

Go to the documentation of this file.
00001 /*
00002  * Video Acceleration API (video decoding)
00003  * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1
00004  *
00005  * Copyright (C) 2008-2009 Splitted-Desktop Systems
00006  *
00007  * This file is part of FFmpeg.
00008  *
00009  * FFmpeg is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2.1 of the License, or (at your option) any later version.
00013  *
00014  * FFmpeg is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Lesser General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public
00020  * License along with FFmpeg; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
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     dprintf(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 /* @} */

Generated on Fri Sep 16 2011 17:17:44 for FFmpeg by  doxygen 1.7.1