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