1 /**************************************************************************
3 * Copyright 2013 Advanced Micro Devices, Inc.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
28 #include "vid_enc_common.h"
30 #include "vl/vl_video_buffer.h"
32 void enc_ReleaseTasks(struct list_head
*head
)
34 struct encode_task
*i
, *next
;
36 if (!head
|| !head
->next
)
39 LIST_FOR_EACH_ENTRY_SAFE(i
, next
, head
, list
) {
40 pipe_resource_reference(&i
->bitstream
, NULL
);
41 i
->buf
->destroy(i
->buf
);
46 void enc_MoveTasks(struct list_head
*from
, struct list_head
*to
)
48 to
->prev
->next
= from
->next
;
49 from
->next
->prev
= to
->prev
;
50 from
->prev
->next
= to
;
51 to
->prev
= from
->prev
;
55 static void enc_GetPictureParamPreset(struct pipe_h264_enc_picture_desc
*picture
)
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;
63 enum pipe_video_profile
enc_TranslateOMXProfileToPipe(unsigned omx_profile
)
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
;
81 return PIPE_VIDEO_PROFILE_UNKNOWN
;
85 unsigned enc_TranslateOMXLevelToPipe(unsigned omx_level
)
88 case OMX_VIDEO_AVCLevel1
:
89 case OMX_VIDEO_AVCLevel1b
:
91 case OMX_VIDEO_AVCLevel11
:
93 case OMX_VIDEO_AVCLevel12
:
95 case OMX_VIDEO_AVCLevel13
:
97 case OMX_VIDEO_AVCLevel2
:
99 case OMX_VIDEO_AVCLevel21
:
101 case OMX_VIDEO_AVCLevel22
:
103 case OMX_VIDEO_AVCLevel3
:
105 case OMX_VIDEO_AVCLevel31
:
107 case OMX_VIDEO_AVCLevel32
:
109 case OMX_VIDEO_AVCLevel4
:
111 case OMX_VIDEO_AVCLevel41
:
114 case OMX_VIDEO_AVCLevel42
:
116 case OMX_VIDEO_AVCLevel5
:
118 case OMX_VIDEO_AVCLevel51
:
123 void vid_enc_BufferEncoded_common(vid_enc_PrivateType
* priv
, OMX_BUFFERHEADERTYPE
* input
, OMX_BUFFERHEADERTYPE
* output
)
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
= {};
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
);
139 task
= LIST_ENTRY(struct encode_task
, inp
->tasks
.next
, list
);
140 LIST_DEL(&task
->list
);
141 LIST_ADDTAIL(&task
->list
, &priv
->used_tasks
);
143 if (!task
->bitstream
)
146 /* ------------- map result buffer ----------------- */
149 pipe_transfer_unmap(priv
->t_pipe
, outp
->transfer
);
151 pipe_resource_reference(&outp
->bitstream
, task
->bitstream
);
152 pipe_resource_reference(&task
->bitstream
, NULL
);
154 box
.width
= outp
->bitstream
->width0
;
155 box
.height
= outp
->bitstream
->height0
;
156 box
.depth
= outp
->bitstream
->depth0
;
158 output
->pBuffer
= priv
->t_pipe
->transfer_map(priv
->t_pipe
, outp
->bitstream
, 0,
159 PIPE_TRANSFER_READ_WRITE
,
160 &box
, &outp
->transfer
);
162 /* ------------- get size of result ----------------- */
164 priv
->codec
->get_feedback(priv
->codec
, task
->feedback
, &size
);
167 output
->nFilledLen
= size
; /* mark buffer as full */
169 /* all output buffers contain exactly one frame */
170 output
->nFlags
= OMX_BUFFERFLAG_ENDOFFRAME
;
172 #if ENABLE_ST_OMX_TIZONIA
173 input
->nFilledLen
= 0; /* mark buffer as empty */
174 enc_MoveTasks(&priv
->used_tasks
, &inp
->tasks
);
179 struct encode_task
*enc_NeedTask_common(vid_enc_PrivateType
* priv
, OMX_VIDEO_PORTDEFINITIONTYPE
*def
)
181 struct pipe_video_buffer templat
= {};
182 struct encode_task
*task
;
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
);
190 /* allocate a new one */
191 task
= CALLOC_STRUCT(encode_task
);
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;
201 task
->buf
= priv
->s_pipe
->create_video_buffer(priv
->s_pipe
, &templat
);
210 void enc_ScaleInput_common(vid_enc_PrivateType
* priv
, OMX_VIDEO_PORTDEFINITIONTYPE
*def
,
211 struct pipe_video_buffer
**vbuf
, unsigned *size
)
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
;
220 if (!priv
->scale_buffer
[priv
->current_scale_buffer
])
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
);
228 for (i
= 0; i
< VL_MAX_SURFACES
; ++i
) {
229 struct u_rect src_rect
;
230 if (!views
[i
] || !dst_surface
[i
])
234 src_rect
.x1
= def
->nFrameWidth
;
235 src_rect
.y1
= def
->nFrameHeight
;
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);
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
;
248 void enc_ControlPicture_common(vid_enc_PrivateType
* priv
, struct pipe_h264_enc_picture_desc
*picture
)
250 struct pipe_h264_enc_rate_control
*rate_ctrl
= &picture
->rate_ctrl
;
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
;
257 case OMX_Video_ControlRateConstant
:
258 rate_ctrl
->rate_ctrl_method
= PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT
;
260 case OMX_Video_ControlRateVariableSkipFrames
:
261 rate_ctrl
->rate_ctrl_method
= PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE_SKIP
;
263 case OMX_Video_ControlRateConstantSkipFrames
:
264 rate_ctrl
->rate_ctrl_method
= PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT_SKIP
;
267 rate_ctrl
->rate_ctrl_method
= PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE
;
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
;
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
;
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
);
285 rate_ctrl
->vbv_buffer_size
= rate_ctrl
->target_bitrate
;
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
;
292 rate_ctrl
->target_bits_picture
= rate_ctrl
->target_bitrate
;
294 rate_ctrl
->peak_bits_picture_integer
= rate_ctrl
->target_bits_picture
;
295 rate_ctrl
->peak_bits_picture_fraction
= 0;
298 picture
->quant_i_frames
= priv
->quant
.nQpI
;
299 picture
->quant_p_frames
= priv
->quant
.nQpP
;
300 picture
->quant_b_frames
= priv
->quant
.nQpB
;
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
);
309 OMX_ERRORTYPE
enc_LoadImage_common(vid_enc_PrivateType
* priv
, OMX_VIDEO_PORTDEFINITIONTYPE
*def
,
310 OMX_BUFFERHEADERTYPE
*buf
,
311 struct pipe_video_buffer
*vbuf
)
313 struct pipe_box box
= {};
314 struct input_buf_private
*inp
= buf
->pInputPortPrivate
;
316 if (!inp
->resource
) {
317 struct pipe_sampler_view
**views
;
320 views
= vbuf
->get_sampler_view_planes(vbuf
);
322 return OMX_ErrorInsufficientResources
;
325 box
.width
= def
->nFrameWidth
;
326 box
.height
= def
->nFrameHeight
;
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;
335 priv
->s_pipe
->texture_subdata(priv
->s_pipe
, views
[1]->texture
, 0,
336 PIPE_TRANSFER_WRITE
, &box
,
337 ptr
, def
->nStride
, 0);
339 struct pipe_blit_info blit
;
340 struct vl_video_buffer
*dst_buf
= (struct vl_video_buffer
*)vbuf
;
342 pipe_transfer_unmap(priv
->s_pipe
, inp
->transfer
);
344 box
.width
= def
->nFrameWidth
;
345 box
.height
= def
->nFrameHeight
;
348 priv
->s_pipe
->resource_copy_region(priv
->s_pipe
,
349 dst_buf
->resources
[0],
350 0, 0, 0, 0, inp
->resource
, 0, &box
);
352 memset(&blit
, 0, sizeof(blit
));
353 blit
.src
.resource
= inp
->resource
;
354 blit
.src
.format
= inp
->resource
->format
;
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;
362 blit
.dst
.resource
= dst_buf
->resources
[1];
363 blit
.dst
.format
= blit
.dst
.resource
->format
;
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
;
370 blit
.mask
= PIPE_MASK_G
;
371 priv
->s_pipe
->blit(priv
->s_pipe
, &blit
);
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);
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
,
386 return OMX_ErrorNone
;