Check the pointer against NULL
[platform/upstream/libva-intel-driver.git] / src / i965_encoder.c
1 /*
2  * Copyright © 2010 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sub license, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors:
25  *    Zhou Chang <chang.zhou@intel.com>
26  *
27  */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <assert.h>
33
34 #include "intel_batchbuffer.h"
35 #include "intel_driver.h"
36
37 #include "i965_defines.h"
38 #include "i965_drv_video.h"
39 #include "i965_encoder.h"
40 #include "gen6_vme.h"
41 #include "gen6_mfc.h"
42
43 extern Bool gen6_mfc_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context);
44 extern Bool gen6_vme_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context);
45 extern Bool gen7_mfc_context_init(VADriverContextP ctx, struct intel_encoder_context *encoder_context);
46
47 VAStatus 
48 i965_CreateSurfaces(VADriverContextP ctx,
49                     int width,
50                     int height,
51                     int format,
52                     int num_surfaces,
53                     VASurfaceID *surfaces);
54
55 static VAStatus
56 intel_encoder_check_yuv_surface(VADriverContextP ctx,
57                                 VAProfile profile,
58                                 struct encode_state *encode_state,
59                                 struct intel_encoder_context *encoder_context)
60 {
61     struct i965_driver_data *i965 = i965_driver_data(ctx);
62     struct i965_surface src_surface, dst_surface;
63     struct object_surface *obj_surface;
64     VAStatus status;
65     VARectangle rect;
66
67     /* releae the temporary surface */
68     if (encoder_context->is_tmp_id) {
69         i965_DestroySurfaces(ctx, &encoder_context->input_yuv_surface, 1);
70         encode_state->input_yuv_object = NULL;
71     }
72
73     encoder_context->is_tmp_id = 0;
74     obj_surface = SURFACE(encode_state->current_render_target);
75     assert(obj_surface && obj_surface->bo);
76
77     if (!obj_surface || !obj_surface->bo)
78         return VA_STATUS_ERROR_INVALID_PARAMETER;
79
80     if (obj_surface->fourcc == VA_FOURCC_NV12) {
81         unsigned int tiling = 0, swizzle = 0;
82
83         dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
84
85         if (tiling == I915_TILING_Y) {
86             encoder_context->input_yuv_surface = encode_state->current_render_target;
87             encode_state->input_yuv_object = obj_surface;
88             return VA_STATUS_SUCCESS;
89         }
90     }
91
92     rect.x = 0;
93     rect.y = 0;
94     rect.width = obj_surface->orig_width;
95     rect.height = obj_surface->orig_height;
96     
97     src_surface.base = (struct object_base *)obj_surface;
98     src_surface.type = I965_SURFACE_TYPE_SURFACE;
99     src_surface.flags = I965_SURFACE_FLAG_FRAME;
100     
101     status = i965_CreateSurfaces(ctx,
102                                  obj_surface->orig_width,
103                                  obj_surface->orig_height,
104                                  VA_RT_FORMAT_YUV420,
105                                  1,
106                                  &encoder_context->input_yuv_surface);
107     assert(status == VA_STATUS_SUCCESS);
108
109     if (status != VA_STATUS_SUCCESS)
110         return status;
111
112     obj_surface = SURFACE(encoder_context->input_yuv_surface);
113     encode_state->input_yuv_object = obj_surface;
114     assert(obj_surface);
115     i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
116     
117     dst_surface.base = (struct object_base *)obj_surface;
118     dst_surface.type = I965_SURFACE_TYPE_SURFACE;
119     dst_surface.flags = I965_SURFACE_FLAG_FRAME;
120
121     status = i965_image_processing(ctx,
122                                    &src_surface,
123                                    &rect,
124                                    &dst_surface,
125                                    &rect);
126     assert(status == VA_STATUS_SUCCESS);
127
128     encoder_context->is_tmp_id = 1;
129
130     return VA_STATUS_SUCCESS;
131 }
132
133 static VAStatus
134 intel_encoder_check_avc_parameter(VADriverContextP ctx,
135                                   struct encode_state *encode_state,
136                                   struct intel_encoder_context *encoder_context)
137 {
138     struct i965_driver_data *i965 = i965_driver_data(ctx);
139     struct object_surface *obj_surface; 
140     struct object_buffer *obj_buffer;
141     VAEncPictureParameterBufferH264 *pic_param = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
142     int i;
143
144     assert(!(pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID));
145
146     if (pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID)
147         goto error;
148
149     obj_surface = SURFACE(pic_param->CurrPic.picture_id);
150     assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
151     
152     if (!obj_surface)
153         goto error;
154
155     encode_state->reconstructed_object = obj_surface;
156     obj_buffer = BUFFER(pic_param->coded_buf);
157     assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
158
159     if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
160         goto error;
161
162     encode_state->coded_buf_object = obj_buffer;
163
164     for (i = 0; i < 16; i++) {
165         if (pic_param->ReferenceFrames[i].flags & VA_PICTURE_H264_INVALID ||
166             pic_param->ReferenceFrames[i].picture_id == VA_INVALID_SURFACE)
167             break;
168         else {
169             obj_surface = SURFACE(pic_param->ReferenceFrames[i].picture_id);
170             assert(obj_surface);
171
172             if (!obj_surface)
173                 goto error;
174
175             if (obj_surface->bo)
176                 encode_state->reference_objects[i] = obj_surface;
177             else
178                 encode_state->reference_objects[i] = NULL; /* FIXME: Warning or Error ??? */
179         }
180     }
181
182     for ( ; i < 16; i++)
183         encode_state->reference_objects[i] = NULL;
184     
185     return VA_STATUS_SUCCESS;
186
187 error:
188     return VA_STATUS_ERROR_INVALID_PARAMETER;
189 }
190
191 static VAStatus
192 intel_encoder_check_mpeg2_parameter(VADriverContextP ctx,
193                                     struct encode_state *encode_state,
194                                     struct intel_encoder_context *encoder_context)
195 {
196     struct i965_driver_data *i965 = i965_driver_data(ctx);
197     VAEncPictureParameterBufferMPEG2 *pic_param = (VAEncPictureParameterBufferMPEG2 *)encode_state->pic_param_ext->buffer;
198     struct object_surface *obj_surface; 
199     struct object_buffer *obj_buffer;
200     int i = 0;
201     
202     obj_surface = SURFACE(pic_param->reconstructed_picture);
203     assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
204     
205     if (!obj_surface)
206         goto error;
207     
208     encode_state->reconstructed_object = obj_surface;    
209     obj_buffer = BUFFER(pic_param->coded_buf);
210     assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
211
212     if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
213         goto error;
214
215     encode_state->coded_buf_object = obj_buffer;
216
217     if (pic_param->picture_type == VAEncPictureTypeIntra) {
218     } else if (pic_param->picture_type == VAEncPictureTypePredictive) {
219         assert(pic_param->forward_reference_picture != VA_INVALID_SURFACE);
220         obj_surface = SURFACE(pic_param->forward_reference_picture);
221         assert(obj_surface && obj_surface->bo);
222
223         if (!obj_surface || !obj_surface->bo)
224             goto error;
225
226         encode_state->reference_objects[i++] = obj_surface;
227     } else if (pic_param->picture_type == VAEncPictureTypeBidirectional) {
228         assert(pic_param->forward_reference_picture != VA_INVALID_SURFACE);
229         obj_surface = SURFACE(pic_param->forward_reference_picture);
230         assert(obj_surface && obj_surface->bo);
231
232         if (!obj_surface || !obj_surface->bo)
233             goto error;
234
235         encode_state->reference_objects[i++] = obj_surface;
236
237         assert(pic_param->backward_reference_picture != VA_INVALID_SURFACE);
238         obj_surface = SURFACE(pic_param->backward_reference_picture);
239         assert(obj_surface && obj_surface->bo);
240
241         if (!obj_surface || !obj_surface->bo)
242             goto error;
243
244         encode_state->reference_objects[i++] = obj_surface;
245     } else 
246         goto error;
247
248     for ( ; i < 16; i++)
249         encode_state->reference_objects[i] = NULL;
250
251     return VA_STATUS_SUCCESS;
252
253 error:
254     return VA_STATUS_ERROR_INVALID_PARAMETER;
255 }
256
257 static VAStatus
258 intel_encoder_sanity_check_input(VADriverContextP ctx,
259                                  VAProfile profile,
260                                  struct encode_state *encode_state,
261                                  struct intel_encoder_context *encoder_context)
262 {
263     VAStatus vaStatus;
264
265     switch (profile) {
266     case VAProfileH264ConstrainedBaseline:
267     case VAProfileH264Main:
268     case VAProfileH264High:
269         vaStatus = intel_encoder_check_avc_parameter(ctx, encode_state, encoder_context);
270         break;
271
272     case VAProfileMPEG2Simple:
273     case VAProfileMPEG2Main:
274         vaStatus = intel_encoder_check_mpeg2_parameter(ctx, encode_state, encoder_context);
275         break;
276
277     default:
278         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
279         break;
280     }
281
282     if (vaStatus != VA_STATUS_SUCCESS)
283         goto out;
284
285     vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
286
287 out:    
288     return vaStatus;
289 }
290  
291 static VAStatus
292 intel_encoder_end_picture(VADriverContextP ctx, 
293                           VAProfile profile, 
294                           union codec_state *codec_state,
295                           struct hw_context *hw_context)
296 {
297     struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
298     struct encode_state *encode_state = &codec_state->encode;
299     VAStatus vaStatus;
300
301     vaStatus = intel_encoder_sanity_check_input(ctx, profile, encode_state, encoder_context);
302
303     if (vaStatus != VA_STATUS_SUCCESS)
304         return vaStatus;
305
306     encoder_context->mfc_brc_prepare(encode_state, encoder_context);
307
308     vaStatus = encoder_context->vme_pipeline(ctx, profile, encode_state, encoder_context);
309
310     if (vaStatus == VA_STATUS_SUCCESS)
311         encoder_context->mfc_pipeline(ctx, profile, encode_state, encoder_context);
312     return VA_STATUS_SUCCESS;
313 }
314
315 static void
316 intel_encoder_context_destroy(void *hw_context)
317 {
318     struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
319
320     encoder_context->mfc_context_destroy(encoder_context->mfc_context);
321     encoder_context->vme_context_destroy(encoder_context->vme_context);
322     intel_batchbuffer_free(encoder_context->base.batch);
323     free(encoder_context);
324 }
325
326 typedef Bool (* hw_init_func)(VADriverContextP, struct intel_encoder_context *);
327
328 static struct hw_context *
329 intel_enc_hw_context_init(VADriverContextP ctx,
330                           struct object_config *obj_config,
331                           hw_init_func vme_context_init,
332                           hw_init_func mfc_context_init)
333 {
334     struct intel_driver_data *intel = intel_driver_data(ctx);
335     struct intel_encoder_context *encoder_context = calloc(1, sizeof(struct intel_encoder_context));
336     int i;
337
338     encoder_context->base.destroy = intel_encoder_context_destroy;
339     encoder_context->base.run = intel_encoder_end_picture;
340     encoder_context->base.batch = intel_batchbuffer_new(intel, I915_EXEC_RENDER, 0);
341     encoder_context->input_yuv_surface = VA_INVALID_SURFACE;
342     encoder_context->is_tmp_id = 0;
343     encoder_context->rate_control_mode = VA_RC_NONE;
344
345     switch (obj_config->profile) {
346     case VAProfileMPEG2Simple:
347     case VAProfileMPEG2Main:
348         encoder_context->codec = CODEC_MPEG2;
349         break;
350         
351     case VAProfileH264ConstrainedBaseline:
352     case VAProfileH264Main:
353     case VAProfileH264High:
354         encoder_context->codec = CODEC_H264;
355         break;
356
357     default:
358         /* Never get here */
359         assert(0);
360         break;
361     }
362
363     for (i = 0; i < obj_config->num_attribs; i++) {
364         if (obj_config->attrib_list[i].type == VAConfigAttribRateControl) {
365             encoder_context->rate_control_mode = obj_config->attrib_list[i].value;
366
367             if (encoder_context->codec == CODEC_MPEG2 &&
368                 encoder_context->rate_control_mode & VA_RC_CBR) {
369                 WARN_ONCE("Don't support CBR for MPEG-2 encoding\n");
370                 encoder_context->rate_control_mode &= ~VA_RC_CBR;
371             }
372
373             break;
374         }
375     }
376
377     vme_context_init(ctx, encoder_context);
378     assert(encoder_context->vme_context);
379     assert(encoder_context->vme_context_destroy);
380     assert(encoder_context->vme_pipeline);
381
382     mfc_context_init(ctx, encoder_context);
383     assert(encoder_context->mfc_context);
384     assert(encoder_context->mfc_context_destroy);
385     assert(encoder_context->mfc_pipeline);
386
387     return (struct hw_context *)encoder_context;
388 }
389
390 struct hw_context *
391 gen6_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
392 {
393     return intel_enc_hw_context_init(ctx, obj_config, gen6_vme_context_init, gen6_mfc_context_init);
394 }
395
396 struct hw_context *
397 gen7_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
398 {
399     return intel_enc_hw_context_init(ctx, obj_config, gen7_vme_context_init, gen7_mfc_context_init);
400 }
401
402 struct hw_context *
403 gen75_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
404 {
405     return intel_enc_hw_context_init(ctx, obj_config, gen75_vme_context_init, gen75_mfc_context_init);
406 }
407
408 struct hw_context *
409 gen8_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
410 {
411     return intel_enc_hw_context_init(ctx, obj_config, gen8_vme_context_init, gen8_mfc_context_init);
412 }
413