st/omx/tizonia: Add H.264 encoder
[mesa.git] / src / gallium / state_trackers / omx / vid_enc_common.c
1 /**************************************************************************
2 *
3 * Copyright 2013 Advanced Micro Devices, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include "vid_enc_common.h"
29
30 #include "vl/vl_video_buffer.h"
31
32 void enc_ReleaseTasks(struct list_head *head)
33 {
34 struct encode_task *i, *next;
35
36 if (!head || !head->next)
37 return;
38
39 LIST_FOR_EACH_ENTRY_SAFE(i, next, head, list) {
40 pipe_resource_reference(&i->bitstream, NULL);
41 i->buf->destroy(i->buf);
42 FREE(i);
43 }
44 }
45
46 void enc_MoveTasks(struct list_head *from, struct list_head *to)
47 {
48 to->prev->next = from->next;
49 from->next->prev = to->prev;
50 from->prev->next = to;
51 to->prev = from->prev;
52 LIST_INITHEAD(from);
53 }
54
55 static void enc_GetPictureParamPreset(struct pipe_h264_enc_picture_desc *picture)
56 {
57 picture->motion_est.enc_disable_sub_mode = 0x000000fe;
58 picture->motion_est.enc_ime2_search_range_x = 0x00000001;
59 picture->motion_est.enc_ime2_search_range_y = 0x00000001;
60 picture->pic_ctrl.enc_constraint_set_flags = 0x00000040;
61 }
62
63 enum pipe_video_profile enc_TranslateOMXProfileToPipe(unsigned omx_profile)
64 {
65 switch (omx_profile) {
66 case OMX_VIDEO_AVCProfileBaseline:
67 return PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE;
68 case OMX_VIDEO_AVCProfileMain:
69 return PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN;
70 case OMX_VIDEO_AVCProfileExtended:
71 return PIPE_VIDEO_PROFILE_MPEG4_AVC_EXTENDED;
72 case OMX_VIDEO_AVCProfileHigh:
73 return PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH;
74 case OMX_VIDEO_AVCProfileHigh10:
75 return PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH10;
76 case OMX_VIDEO_AVCProfileHigh422:
77 return PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH422;
78 case OMX_VIDEO_AVCProfileHigh444:
79 return PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH444;
80 default:
81 return PIPE_VIDEO_PROFILE_UNKNOWN;
82 }
83 }
84
85 unsigned enc_TranslateOMXLevelToPipe(unsigned omx_level)
86 {
87 switch (omx_level) {
88 case OMX_VIDEO_AVCLevel1:
89 case OMX_VIDEO_AVCLevel1b:
90 return 10;
91 case OMX_VIDEO_AVCLevel11:
92 return 11;
93 case OMX_VIDEO_AVCLevel12:
94 return 12;
95 case OMX_VIDEO_AVCLevel13:
96 return 13;
97 case OMX_VIDEO_AVCLevel2:
98 return 20;
99 case OMX_VIDEO_AVCLevel21:
100 return 21;
101 case OMX_VIDEO_AVCLevel22:
102 return 22;
103 case OMX_VIDEO_AVCLevel3:
104 return 30;
105 case OMX_VIDEO_AVCLevel31:
106 return 31;
107 case OMX_VIDEO_AVCLevel32:
108 return 32;
109 case OMX_VIDEO_AVCLevel4:
110 return 40;
111 case OMX_VIDEO_AVCLevel41:
112 return 41;
113 default:
114 case OMX_VIDEO_AVCLevel42:
115 return 42;
116 case OMX_VIDEO_AVCLevel5:
117 return 50;
118 case OMX_VIDEO_AVCLevel51:
119 return 51;
120 }
121 }
122
123 void vid_enc_BufferEncoded_common(vid_enc_PrivateType * priv, OMX_BUFFERHEADERTYPE* input, OMX_BUFFERHEADERTYPE* output)
124 {
125 struct output_buf_private *outp = output->pOutputPortPrivate;
126 struct input_buf_private *inp = input->pInputPortPrivate;
127 struct encode_task *task;
128 struct pipe_box box = {};
129 unsigned size;
130
131 #if ENABLE_ST_OMX_BELLAGIO
132 if (!inp || LIST_IS_EMPTY(&inp->tasks)) {
133 input->nFilledLen = 0; /* mark buffer as empty */
134 enc_MoveTasks(&priv->used_tasks, &inp->tasks);
135 return;
136 }
137 #endif
138
139 task = LIST_ENTRY(struct encode_task, inp->tasks.next, list);
140 LIST_DEL(&task->list);
141 LIST_ADDTAIL(&task->list, &priv->used_tasks);
142
143 if (!task->bitstream)
144 return;
145
146 /* ------------- map result buffer ----------------- */
147
148 if (outp->transfer)
149 pipe_transfer_unmap(priv->t_pipe, outp->transfer);
150
151 pipe_resource_reference(&outp->bitstream, task->bitstream);
152 pipe_resource_reference(&task->bitstream, NULL);
153
154 box.width = outp->bitstream->width0;
155 box.height = outp->bitstream->height0;
156 box.depth = outp->bitstream->depth0;
157
158 output->pBuffer = priv->t_pipe->transfer_map(priv->t_pipe, outp->bitstream, 0,
159 PIPE_TRANSFER_READ_WRITE,
160 &box, &outp->transfer);
161
162 /* ------------- get size of result ----------------- */
163
164 priv->codec->get_feedback(priv->codec, task->feedback, &size);
165
166 output->nOffset = 0;
167 output->nFilledLen = size; /* mark buffer as full */
168
169 /* all output buffers contain exactly one frame */
170 output->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
171
172 #if ENABLE_ST_OMX_TIZONIA
173 input->nFilledLen = 0; /* mark buffer as empty */
174 enc_MoveTasks(&priv->used_tasks, &inp->tasks);
175 #endif
176 }
177
178
179 struct encode_task *enc_NeedTask_common(vid_enc_PrivateType * priv, OMX_VIDEO_PORTDEFINITIONTYPE *def)
180 {
181 struct pipe_video_buffer templat = {};
182 struct encode_task *task;
183
184 if (!LIST_IS_EMPTY(&priv->free_tasks)) {
185 task = LIST_ENTRY(struct encode_task, priv->free_tasks.next, list);
186 LIST_DEL(&task->list);
187 return task;
188 }
189
190 /* allocate a new one */
191 task = CALLOC_STRUCT(encode_task);
192 if (!task)
193 return NULL;
194
195 templat.buffer_format = PIPE_FORMAT_NV12;
196 templat.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420;
197 templat.width = def->nFrameWidth;
198 templat.height = def->nFrameHeight;
199 templat.interlaced = false;
200
201 task->buf = priv->s_pipe->create_video_buffer(priv->s_pipe, &templat);
202 if (!task->buf) {
203 FREE(task);
204 return NULL;
205 }
206
207 return task;
208 }
209
210 void enc_ScaleInput_common(vid_enc_PrivateType * priv, OMX_VIDEO_PORTDEFINITIONTYPE *def,
211 struct pipe_video_buffer **vbuf, unsigned *size)
212 {
213 struct pipe_video_buffer *src_buf = *vbuf;
214 struct vl_compositor *compositor = &priv->compositor;
215 struct vl_compositor_state *s = &priv->cstate;
216 struct pipe_sampler_view **views;
217 struct pipe_surface **dst_surface;
218 unsigned i;
219
220 if (!priv->scale_buffer[priv->current_scale_buffer])
221 return;
222
223 views = src_buf->get_sampler_view_planes(src_buf);
224 dst_surface = priv->scale_buffer[priv->current_scale_buffer]->get_surfaces
225 (priv->scale_buffer[priv->current_scale_buffer]);
226 vl_compositor_clear_layers(s);
227
228 for (i = 0; i < VL_MAX_SURFACES; ++i) {
229 struct u_rect src_rect;
230 if (!views[i] || !dst_surface[i])
231 continue;
232 src_rect.x0 = 0;
233 src_rect.y0 = 0;
234 src_rect.x1 = def->nFrameWidth;
235 src_rect.y1 = def->nFrameHeight;
236 if (i > 0) {
237 src_rect.x1 /= 2;
238 src_rect.y1 /= 2;
239 }
240 vl_compositor_set_rgba_layer(s, compositor, 0, views[i], &src_rect, NULL, NULL);
241 vl_compositor_render(s, compositor, dst_surface[i], NULL, false);
242 }
243 *size = priv->scale.xWidth * priv->scale.xHeight * 2;
244 *vbuf = priv->scale_buffer[priv->current_scale_buffer++];
245 priv->current_scale_buffer %= OMX_VID_ENC_NUM_SCALING_BUFFERS;
246 }
247
248 void enc_ControlPicture_common(vid_enc_PrivateType * priv, struct pipe_h264_enc_picture_desc *picture)
249 {
250 struct pipe_h264_enc_rate_control *rate_ctrl = &picture->rate_ctrl;
251
252 /* Get bitrate from port */
253 switch (priv->bitrate.eControlRate) {
254 case OMX_Video_ControlRateVariable:
255 rate_ctrl->rate_ctrl_method = PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE;
256 break;
257 case OMX_Video_ControlRateConstant:
258 rate_ctrl->rate_ctrl_method = PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT;
259 break;
260 case OMX_Video_ControlRateVariableSkipFrames:
261 rate_ctrl->rate_ctrl_method = PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE_SKIP;
262 break;
263 case OMX_Video_ControlRateConstantSkipFrames:
264 rate_ctrl->rate_ctrl_method = PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT_SKIP;
265 break;
266 default:
267 rate_ctrl->rate_ctrl_method = PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE;
268 break;
269 }
270
271 rate_ctrl->frame_rate_den = OMX_VID_ENC_CONTROL_FRAME_RATE_DEN_DEFAULT;
272 rate_ctrl->frame_rate_num = ((priv->frame_rate) >> 16) * rate_ctrl->frame_rate_den;
273
274 if (rate_ctrl->rate_ctrl_method != PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE) {
275 if (priv->bitrate.nTargetBitrate < OMX_VID_ENC_BITRATE_MIN)
276 rate_ctrl->target_bitrate = OMX_VID_ENC_BITRATE_MIN;
277 else if (priv->bitrate.nTargetBitrate < OMX_VID_ENC_BITRATE_MAX)
278 rate_ctrl->target_bitrate = priv->bitrate.nTargetBitrate;
279 else
280 rate_ctrl->target_bitrate = OMX_VID_ENC_BITRATE_MAX;
281 rate_ctrl->peak_bitrate = rate_ctrl->target_bitrate;
282 if (rate_ctrl->target_bitrate < OMX_VID_ENC_BITRATE_MEDIAN)
283 rate_ctrl->vbv_buffer_size = MIN2((rate_ctrl->target_bitrate * 2.75), OMX_VID_ENC_BITRATE_MEDIAN);
284 else
285 rate_ctrl->vbv_buffer_size = rate_ctrl->target_bitrate;
286
287 if (rate_ctrl->frame_rate_num) {
288 unsigned long long t = rate_ctrl->target_bitrate;
289 t *= rate_ctrl->frame_rate_den;
290 rate_ctrl->target_bits_picture = t / rate_ctrl->frame_rate_num;
291 } else {
292 rate_ctrl->target_bits_picture = rate_ctrl->target_bitrate;
293 }
294 rate_ctrl->peak_bits_picture_integer = rate_ctrl->target_bits_picture;
295 rate_ctrl->peak_bits_picture_fraction = 0;
296 }
297
298 picture->quant_i_frames = priv->quant.nQpI;
299 picture->quant_p_frames = priv->quant.nQpP;
300 picture->quant_b_frames = priv->quant.nQpB;
301
302 picture->frame_num = priv->frame_num;
303 picture->ref_idx_l0 = priv->ref_idx_l0;
304 picture->ref_idx_l1 = priv->ref_idx_l1;
305 picture->enable_vui = (picture->rate_ctrl.frame_rate_num != 0);
306 enc_GetPictureParamPreset(picture);
307 }
308
309 OMX_ERRORTYPE enc_LoadImage_common(vid_enc_PrivateType * priv, OMX_VIDEO_PORTDEFINITIONTYPE *def,
310 OMX_BUFFERHEADERTYPE *buf,
311 struct pipe_video_buffer *vbuf)
312 {
313 struct pipe_box box = {};
314 struct input_buf_private *inp = buf->pInputPortPrivate;
315
316 if (!inp->resource) {
317 struct pipe_sampler_view **views;
318 void *ptr;
319
320 views = vbuf->get_sampler_view_planes(vbuf);
321 if (!views)
322 return OMX_ErrorInsufficientResources;
323
324 ptr = buf->pBuffer;
325 box.width = def->nFrameWidth;
326 box.height = def->nFrameHeight;
327 box.depth = 1;
328 priv->s_pipe->texture_subdata(priv->s_pipe, views[0]->texture, 0,
329 PIPE_TRANSFER_WRITE, &box,
330 ptr, def->nStride, 0);
331 ptr = ((uint8_t*)buf->pBuffer) + (def->nStride * box.height);
332 box.width = def->nFrameWidth / 2;
333 box.height = def->nFrameHeight / 2;
334 box.depth = 1;
335 priv->s_pipe->texture_subdata(priv->s_pipe, views[1]->texture, 0,
336 PIPE_TRANSFER_WRITE, &box,
337 ptr, def->nStride, 0);
338 } else {
339 struct pipe_blit_info blit;
340 struct vl_video_buffer *dst_buf = (struct vl_video_buffer *)vbuf;
341
342 pipe_transfer_unmap(priv->s_pipe, inp->transfer);
343
344 box.width = def->nFrameWidth;
345 box.height = def->nFrameHeight;
346 box.depth = 1;
347
348 priv->s_pipe->resource_copy_region(priv->s_pipe,
349 dst_buf->resources[0],
350 0, 0, 0, 0, inp->resource, 0, &box);
351
352 memset(&blit, 0, sizeof(blit));
353 blit.src.resource = inp->resource;
354 blit.src.format = inp->resource->format;
355
356 blit.src.box.x = 0;
357 blit.src.box.y = def->nFrameHeight;
358 blit.src.box.width = def->nFrameWidth;
359 blit.src.box.height = def->nFrameHeight / 2 ;
360 blit.src.box.depth = 1;
361
362 blit.dst.resource = dst_buf->resources[1];
363 blit.dst.format = blit.dst.resource->format;
364
365 blit.dst.box.width = def->nFrameWidth / 2;
366 blit.dst.box.height = def->nFrameHeight / 2;
367 blit.dst.box.depth = 1;
368 blit.filter = PIPE_TEX_FILTER_NEAREST;
369
370 blit.mask = PIPE_MASK_G;
371 priv->s_pipe->blit(priv->s_pipe, &blit);
372
373 blit.src.box.x = 1;
374 blit.mask = PIPE_MASK_R;
375 priv->s_pipe->blit(priv->s_pipe, &blit);
376 priv->s_pipe->flush(priv->s_pipe, NULL, 0);
377
378 box.width = inp->resource->width0;
379 box.height = inp->resource->height0;
380 box.depth = inp->resource->depth0;
381 buf->pBuffer = priv->s_pipe->transfer_map(priv->s_pipe, inp->resource, 0,
382 PIPE_TRANSFER_WRITE, &box,
383 &inp->transfer);
384 }
385
386 return OMX_ErrorNone;
387 }