MPEG-2 encoding path
[profile/ivi/vaapi-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 void
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     }
75
76     encoder_context->is_tmp_id = 0;
77     obj_surface = SURFACE(encode_state->current_render_target);
78     assert(obj_surface && obj_surface->bo);
79
80     if (obj_surface->fourcc == VA_FOURCC('N', 'V', '1', '2')) {
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             return;
88         }
89     }
90
91     rect.x = 0;
92     rect.y = 0;
93     rect.width = obj_surface->orig_width;
94     rect.height = obj_surface->orig_height;
95     
96     src_surface.id = encode_state->current_render_target;
97     src_surface.type = I965_SURFACE_TYPE_SURFACE;
98     src_surface.flags = I965_SURFACE_FLAG_FRAME;
99     
100     status = i965_CreateSurfaces(ctx,
101                                  obj_surface->orig_width,
102                                  obj_surface->orig_height,
103                                  VA_RT_FORMAT_YUV420,
104                                  1,
105                                  &encoder_context->input_yuv_surface);
106     assert(status == VA_STATUS_SUCCESS);
107     obj_surface = SURFACE(encoder_context->input_yuv_surface);
108     i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N', 'V', '1', '2'), SUBSAMPLE_YUV420);
109     
110     dst_surface.id = encoder_context->input_yuv_surface;
111     dst_surface.type = I965_SURFACE_TYPE_SURFACE;
112     dst_surface.flags = I965_SURFACE_FLAG_FRAME;
113
114     status = i965_image_processing(ctx,
115                                    &src_surface,
116                                    &rect,
117                                    &dst_surface,
118                                    &rect);
119     assert(status == VA_STATUS_SUCCESS);
120
121     encoder_context->is_tmp_id = 1;
122 }
123
124 static void 
125 intel_encoder_end_picture(VADriverContextP ctx, 
126                           VAProfile profile, 
127                           union codec_state *codec_state,
128                           struct hw_context *hw_context)
129 {
130     struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
131     struct encode_state *encode_state = &codec_state->encode;
132     VAStatus vaStatus;
133
134     intel_encoder_check_yuv_surface(ctx, profile, encode_state, encoder_context);
135
136     encoder_context->mfc_brc_prepare(encode_state, encoder_context);
137
138     vaStatus = encoder_context->vme_pipeline(ctx, profile, encode_state, encoder_context);
139
140     if (vaStatus == VA_STATUS_SUCCESS)
141         encoder_context->mfc_pipeline(ctx, profile, encode_state, encoder_context);
142 }
143
144 static void
145 intel_encoder_context_destroy(void *hw_context)
146 {
147     struct intel_encoder_context *encoder_context = (struct intel_encoder_context *)hw_context;
148
149     encoder_context->mfc_context_destroy(encoder_context->mfc_context);
150     encoder_context->vme_context_destroy(encoder_context->vme_context);
151     intel_batchbuffer_free(encoder_context->base.batch);
152     free(encoder_context);
153 }
154
155 struct hw_context *
156 gen6_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
157 {
158     struct intel_driver_data *intel = intel_driver_data(ctx);
159     struct intel_encoder_context *encoder_context = calloc(1, sizeof(struct intel_encoder_context));
160     int i;
161
162     encoder_context->base.destroy = intel_encoder_context_destroy;
163     encoder_context->base.run = intel_encoder_end_picture;
164     encoder_context->base.batch = intel_batchbuffer_new(intel, I915_EXEC_RENDER, 0);
165     encoder_context->rate_control_mode = VA_RC_NONE;
166     encoder_context->profile = obj_config->profile;
167
168     for (i = 0; i < obj_config->num_attribs; i++) {
169         if (obj_config->attrib_list[i].type == VAConfigAttribRateControl) {
170             encoder_context->rate_control_mode = obj_config->attrib_list[i].value;
171             break;
172         }
173     }
174
175     gen6_vme_context_init(ctx, encoder_context);
176     assert(encoder_context->vme_context);
177     assert(encoder_context->vme_context_destroy);
178     assert(encoder_context->vme_pipeline);
179
180     gen6_mfc_context_init(ctx, encoder_context);
181     assert(encoder_context->mfc_context);
182     assert(encoder_context->mfc_context_destroy);
183     assert(encoder_context->mfc_pipeline);
184
185     return (struct hw_context *)encoder_context;
186 }
187
188 struct hw_context *
189 gen7_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
190 {
191     struct intel_driver_data *intel = intel_driver_data(ctx);
192     struct intel_encoder_context *encoder_context = calloc(1, sizeof(struct intel_encoder_context));
193     int i;
194
195     encoder_context->base.destroy = intel_encoder_context_destroy;
196     encoder_context->base.run = intel_encoder_end_picture;
197     encoder_context->base.batch = intel_batchbuffer_new(intel, I915_EXEC_RENDER, 0);
198     encoder_context->input_yuv_surface = VA_INVALID_SURFACE;
199     encoder_context->is_tmp_id = 0;
200     encoder_context->rate_control_mode = VA_RC_NONE;
201     encoder_context->profile = obj_config->profile;
202
203     for (i = 0; i < obj_config->num_attribs; i++) {
204         if (obj_config->attrib_list[i].type == VAConfigAttribRateControl) {
205             encoder_context->rate_control_mode = obj_config->attrib_list[i].value;
206             break;
207         }
208     }
209
210     gen6_vme_context_init(ctx, encoder_context);
211     assert(encoder_context->vme_context);
212     assert(encoder_context->vme_context_destroy);
213     assert(encoder_context->vme_pipeline);
214
215     gen7_mfc_context_init(ctx, encoder_context);
216     assert(encoder_context->mfc_context);
217     assert(encoder_context->mfc_context_destroy);
218     assert(encoder_context->mfc_pipeline);
219
220     return (struct hw_context *)encoder_context;
221 }
222
223 struct hw_context *
224 gen75_enc_hw_context_init(VADriverContextP ctx, struct object_config *obj_config)
225 {
226     struct intel_driver_data *intel = intel_driver_data(ctx);
227     struct intel_encoder_context *encoder_context = calloc(1, sizeof(struct intel_encoder_context));
228     int i;
229
230     encoder_context->base.destroy = intel_encoder_context_destroy;
231     encoder_context->base.run = intel_encoder_end_picture;
232     encoder_context->base.batch = intel_batchbuffer_new(intel, I915_EXEC_RENDER, 0);
233     encoder_context->input_yuv_surface = VA_INVALID_SURFACE;
234     encoder_context->is_tmp_id = 0;
235     encoder_context->rate_control_mode = VA_RC_NONE;
236     encoder_context->profile = obj_config->profile;
237
238     for (i = 0; i < obj_config->num_attribs; i++) {
239         if (obj_config->attrib_list[i].type == VAConfigAttribRateControl) {
240             encoder_context->rate_control_mode = obj_config->attrib_list[i].value;
241             break;
242         }
243     }
244
245     gen75_vme_context_init(ctx, encoder_context);
246     assert(encoder_context->vme_context);
247     assert(encoder_context->vme_context_destroy);
248     assert(encoder_context->vme_pipeline);
249
250     gen75_mfc_context_init(ctx, encoder_context);
251     assert(encoder_context->mfc_context);
252     assert(encoder_context->mfc_context_destroy);
253     assert(encoder_context->mfc_pipeline);
254
255     return (struct hw_context *)encoder_context;
256 }