VPP: Fix Coverity alert on unitialized vpp_kernels
[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 static VAStatus
48 intel_encoder_check_yuv_surface(VADriverContextP ctx,
49                                 VAProfile profile,
50                                 struct encode_state *encode_state,
51                                 struct intel_encoder_context *encoder_context)
52 {
53     struct i965_driver_data *i965 = i965_driver_data(ctx);
54     struct i965_surface src_surface, dst_surface;
55     struct object_surface *obj_surface;
56     VAStatus status;
57     VARectangle rect;
58
59     /* releae the temporary surface */
60     if (encoder_context->is_tmp_id) {
61         i965_DestroySurfaces(ctx, &encoder_context->input_yuv_surface, 1);
62         encode_state->input_yuv_object = NULL;
63     }
64
65     encoder_context->is_tmp_id = 0;
66     obj_surface = SURFACE(encode_state->current_render_target);
67     assert(obj_surface && obj_surface->bo);
68
69     if (!obj_surface || !obj_surface->bo)
70         return VA_STATUS_ERROR_INVALID_PARAMETER;
71
72     if (obj_surface->fourcc == VA_FOURCC_NV12) {
73         unsigned int tiling = 0, swizzle = 0;
74
75         dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
76
77         if (tiling == I915_TILING_Y) {
78             encoder_context->input_yuv_surface = encode_state->current_render_target;
79             encode_state->input_yuv_object = obj_surface;
80             return VA_STATUS_SUCCESS;
81         }
82     }
83
84     rect.x = 0;
85     rect.y = 0;
86     rect.width = obj_surface->orig_width;
87     rect.height = obj_surface->orig_height;
88     
89     src_surface.base = (struct object_base *)obj_surface;
90     src_surface.type = I965_SURFACE_TYPE_SURFACE;
91     src_surface.flags = I965_SURFACE_FLAG_FRAME;
92     
93     status = i965_CreateSurfaces(ctx,
94                                  obj_surface->orig_width,
95                                  obj_surface->orig_height,
96                                  VA_RT_FORMAT_YUV420,
97                                  1,
98                                  &encoder_context->input_yuv_surface);
99     assert(status == VA_STATUS_SUCCESS);
100
101     if (status != VA_STATUS_SUCCESS)
102         return status;
103
104     obj_surface = SURFACE(encoder_context->input_yuv_surface);
105     encode_state->input_yuv_object = obj_surface;
106     assert(obj_surface);
107     i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
108     
109     dst_surface.base = (struct object_base *)obj_surface;
110     dst_surface.type = I965_SURFACE_TYPE_SURFACE;
111     dst_surface.flags = I965_SURFACE_FLAG_FRAME;
112
113     status = i965_image_processing(ctx,
114                                    &src_surface,
115                                    &rect,
116                                    &dst_surface,
117                                    &rect);
118     assert(status == VA_STATUS_SUCCESS);
119
120     encoder_context->is_tmp_id = 1;
121
122     return VA_STATUS_SUCCESS;
123 }
124
125 static VAStatus
126 intel_encoder_check_misc_parameter(VADriverContextP ctx,
127                                   struct encode_state *encode_state,
128                                   struct intel_encoder_context *encoder_context)
129 {
130
131     if (encode_state->misc_param[VAEncMiscParameterTypeQualityLevel] &&
132         encode_state->misc_param[VAEncMiscParameterTypeQualityLevel]->buffer) {
133         VAEncMiscParameterBuffer* pMiscParam = (VAEncMiscParameterBuffer*)encode_state->misc_param[VAEncMiscParameterTypeQualityLevel]->buffer;
134         VAEncMiscParameterBufferQualityLevel* param_quality_level = (VAEncMiscParameterBufferQualityLevel*)pMiscParam->data;
135         encoder_context->quality_level = param_quality_level->quality_level;
136
137         if (encoder_context->quality_level == 0)
138             encoder_context->quality_level = ENCODER_DEFAULT_QUALITY;
139         else if (encoder_context->quality_level > encoder_context->quality_range)
140             goto error;
141    }
142
143     return VA_STATUS_SUCCESS;
144
145 error:
146     return VA_STATUS_ERROR_INVALID_PARAMETER;
147 }
148
149 static VAStatus
150 intel_encoder_check_avc_parameter(VADriverContextP ctx,
151                                   struct encode_state *encode_state,
152                                   struct intel_encoder_context *encoder_context)
153 {
154     struct i965_driver_data *i965 = i965_driver_data(ctx);
155     struct object_surface *obj_surface; 
156     struct object_buffer *obj_buffer;
157     VAEncPictureParameterBufferH264 *pic_param = (VAEncPictureParameterBufferH264 *)encode_state->pic_param_ext->buffer;
158     int i;
159
160     assert(!(pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID));
161
162     if (pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID)
163         goto error;
164
165     obj_surface = SURFACE(pic_param->CurrPic.picture_id);
166     assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
167     
168     if (!obj_surface)
169         goto error;
170
171     encode_state->reconstructed_object = obj_surface;
172     obj_buffer = BUFFER(pic_param->coded_buf);
173     assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
174
175     if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
176         goto error;
177
178     encode_state->coded_buf_object = obj_buffer;
179
180     for (i = 0; i < 16; i++) {
181         if (pic_param->ReferenceFrames[i].flags & VA_PICTURE_H264_INVALID ||
182             pic_param->ReferenceFrames[i].picture_id == VA_INVALID_SURFACE)
183             break;
184         else {
185             obj_surface = SURFACE(pic_param->ReferenceFrames[i].picture_id);
186             assert(obj_surface);
187
188             if (!obj_surface)
189                 goto error;
190
191             if (obj_surface->bo)
192                 encode_state->reference_objects[i] = obj_surface;
193             else
194                 encode_state->reference_objects[i] = NULL; /* FIXME: Warning or Error ??? */
195         }
196     }
197
198     for ( ; i < 16; i++)
199         encode_state->reference_objects[i] = NULL;
200     
201     return VA_STATUS_SUCCESS;
202
203 error:
204     return VA_STATUS_ERROR_INVALID_PARAMETER;
205 }
206
207 static VAStatus
208 intel_encoder_check_mpeg2_parameter(VADriverContextP ctx,
209                                     struct encode_state *encode_state,
210                                     struct intel_encoder_context *encoder_context)
211 {
212     struct i965_driver_data *i965 = i965_driver_data(ctx);
213     VAEncPictureParameterBufferMPEG2 *pic_param = (VAEncPictureParameterBufferMPEG2 *)encode_state->pic_param_ext->buffer;
214     struct object_surface *obj_surface; 
215     struct object_buffer *obj_buffer;
216     int i = 0;
217     
218     obj_surface = SURFACE(pic_param->reconstructed_picture);
219     assert(obj_surface); /* It is possible the store buffer isn't allocated yet */
220     
221     if (!obj_surface)
222         goto error;
223     
224     encode_state->reconstructed_object = obj_surface;    
225     obj_buffer = BUFFER(pic_param->coded_buf);
226     assert(obj_buffer && obj_buffer->buffer_store && obj_buffer->buffer_store->bo);
227
228     if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
229         goto error;
230
231     encode_state->coded_buf_object = obj_buffer;
232
233     if (pic_param->picture_type == VAEncPictureTypeIntra) {
234     } else if (pic_param->picture_type == VAEncPictureTypePredictive) {
235         assert(pic_param->forward_reference_picture != VA_INVALID_SURFACE);
236         obj_surface = SURFACE(pic_param->forward_reference_picture);
237         assert(obj_surface && obj_surface->bo);
238
239         if (!obj_surface || !obj_surface->bo)
240             goto error;
241
242         encode_state->reference_objects[i++] = obj_surface;
243     } else if (pic_param->picture_type == VAEncPictureTypeBidirectional) {
244         assert(pic_param->forward_reference_picture != VA_INVALID_SURFACE);
245         obj_surface = SURFACE(pic_param->forward_reference_picture);
246         assert(obj_surface && obj_surface->bo);
247
248         if (!obj_surface || !obj_surface->bo)
249             goto error;
250
251         encode_state->reference_objects[i++] = obj_surface;
252
253         assert(pic_param->backward_reference_picture != VA_INVALID_SURFACE);
254         obj_surface = SURFACE(pic_param->backward_reference_picture);
255         assert(obj_surface && obj_surface->bo);
256
257         if (!obj_surface || !obj_surface->bo)
258             goto error;
259
260         encode_state->reference_objects[i++] = obj_surface;
261     } else 
262         goto error;
263
264     for ( ; i < 16; i++)
265         encode_state->reference_objects[i] = NULL;
266
267     return VA_STATUS_SUCCESS;
268
269 error:
270     return VA_STATUS_ERROR_INVALID_PARAMETER;
271 }
272
273 static VAStatus
274 intel_encoder_sanity_check_input(VADriverContextP ctx,
275                                  VAProfile profile,
276                                  struct encode_state *encode_state,
277                                  struct intel_encoder_context *encoder_context)
278 {
279     VAStatus vaStatus;
280
281     switch (profile) {
282     case VAProfileH264ConstrainedBaseline:
283     case VAProfileH264Main:
284     case VAProfileH264High:
285     case VAProfileH264MultiviewHigh:
286     case VAProfileH264StereoHigh:
287         vaStatus = intel_encoder_check_avc_parameter(ctx, encode_state, encoder_context);
288         break;
289
290     case VAProfileMPEG2Simple:
291     case VAProfileMPEG2Main:
292         vaStatus = intel_encoder_check_mpeg2_parameter(ctx, encode_state, encoder_context);
293         break;
294
295     default:
296         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
297         break;
298     }
299
300     if (vaStatus != VA_STATUS_SUCCESS)
301         goto out;
302
303     vaStatus = intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
304
305     if (vaStatus == VA_STATUS_SUCCESS)
306         vaStatus = intel_encoder_check_misc_parameter(ctx, encode_state, encoder_context);
307
308 out:    
309     return vaStatus;
310 }
311  
312 static VAStatus
313 intel_encoder_end_picture(VADriverContextP ctx, 
314                           VAProfile profile, 
315                           union codec_state *codec_state,
316                           struct hw_context *hw_context)
317 {
318     struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
319     struct encode_state *encode_state = &codec_state->encode;
320     VAStatus vaStatus;
321
322     vaStatus = intel_encoder_sanity_check_input(ctx, profile, encode_state, encoder_context);
323
324     if (vaStatus != VA_STATUS_SUCCESS)
325         return vaStatus;
326
327     encoder_context->mfc_brc_prepare(encode_state, encoder_context);
328
329     vaStatus = encoder_context->vme_pipeline(ctx, profile, encode_state, encoder_context);
330
331     if (vaStatus == VA_STATUS_SUCCESS)
332         encoder_context->mfc_pipeline(ctx, profile, encode_state, encoder_context);
333     return VA_STATUS_SUCCESS;
334 }
335
336 static void
337 intel_encoder_context_destroy(void *hw_context)
338 {
339     struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
340
341     encoder_context->mfc_context_destroy(encoder_context->mfc_context);
342     encoder_context->vme_context_destroy(encoder_context->vme_context);
343     intel_batchbuffer_free(encoder_context->base.batch);
344     free(encoder_context);
345 }
346
347 typedef Bool (* hw_init_func)(VADriverContextP, struct intel_encoder_context *);
348
349 static struct hw_context *
350 intel_enc_hw_context_init(VADriverContextP ctx,
351                           struct object_config *obj_config,
352                           hw_init_func vme_context_init,
353                           hw_init_func mfc_context_init)
354 {
355     struct intel_driver_data *intel = intel_driver_data(ctx);
356     struct intel_encoder_context *encoder_context = calloc(1, sizeof(struct intel_encoder_context));
357     int i;
358
359     encoder_context->base.destroy = intel_encoder_context_destroy;
360     encoder_context->base.run = intel_encoder_end_picture;
361     encoder_context->base.batch = intel_batchbuffer_new(intel, I915_EXEC_RENDER, 0);
362     encoder_context->input_yuv_surface = VA_INVALID_SURFACE;
363     encoder_context->is_tmp_id = 0;
364     encoder_context->rate_control_mode = VA_RC_NONE;
365     encoder_context->quality_level = ENCODER_DEFAULT_QUALITY;
366     encoder_context->quality_range = 1;
367
368     switch (obj_config->profile) {
369     case VAProfileMPEG2Simple:
370     case VAProfileMPEG2Main:
371         encoder_context->codec = CODEC_MPEG2;
372         break;
373         
374     case VAProfileH264ConstrainedBaseline:
375     case VAProfileH264Main:
376     case VAProfileH264High:
377         encoder_context->codec = CODEC_H264;
378         encoder_context->quality_range = ENCODER_QUALITY_RANGE;
379         break;
380
381     case VAProfileH264StereoHigh:
382     case VAProfileH264MultiviewHigh:
383         encoder_context->codec = CODEC_H264_MVC;
384         break;
385
386     default:
387         /* Never get here */
388         assert(0);
389         break;
390     }
391
392     for (i = 0; i < obj_config->num_attribs; i++) {
393         if (obj_config->attrib_list[i].type == VAConfigAttribRateControl) {
394             encoder_context->rate_control_mode = obj_config->attrib_list[i].value;
395
396             if (encoder_context->codec == CODEC_MPEG2 &&
397                 encoder_context->rate_control_mode & VA_RC_CBR) {
398                 WARN_ONCE("Don't support CBR for MPEG-2 encoding\n");
399                 encoder_context->rate_control_mode &= ~VA_RC_CBR;
400             }
401
402             break;
403         }
404     }
405
406     vme_context_init(ctx, encoder_context);
407     assert(encoder_context->vme_context);
408     assert(encoder_context->vme_context_destroy);
409     assert(encoder_context->vme_pipeline);
410
411     mfc_context_init(ctx, encoder_context);
412     assert(encoder_context->mfc_context);
413     assert(encoder_context->mfc_context_destroy);
414     assert(encoder_context->mfc_pipeline);
415
416     return (struct hw_context *)encoder_context;
417 }
418
419 struct hw_context *
420 gen6_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
421 {
422     return intel_enc_hw_context_init(ctx, obj_config, gen6_vme_context_init, gen6_mfc_context_init);
423 }
424
425 struct hw_context *
426 gen7_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
427 {
428
429     return intel_enc_hw_context_init(ctx, obj_config, gen7_vme_context_init, gen7_mfc_context_init);
430 }
431
432 struct hw_context *
433 gen75_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
434 {
435     return intel_enc_hw_context_init(ctx, obj_config, gen75_vme_context_init, gen75_mfc_context_init);
436 }
437
438 struct hw_context *
439 gen8_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
440 {
441     return intel_enc_hw_context_init(ctx, obj_config, gen8_vme_context_init, gen8_mfc_context_init);
442 }
443