1 /*
2 * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
3 * Copyright (c) Imagination Technologies Limited, UK
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 * Elaine Wang <elaine.wang@intel.com>
27 * Zeng Li <zeng.li@intel.com>
28 * Edward Lin <edward.lin@intel.com>
29 *
30 */
31
32 #include "psb_drv_video.h"
33 //#include "tng_H263ES.h"
34 #include "tng_hostheader.h"
35 #include "tng_hostcode.h"
36 #include "psb_def.h"
37 #include "psb_drv_debug.h"
38 #include "psb_cmdbuf.h"
39 #include "psb_buffer.h"
40 #include <stdio.h>
41 #include "psb_output.h"
42 #include "tng_picmgmt.h"
43 #include "tng_hostbias.h"
44 #include "tng_hostair.h"
45 #ifdef _TOPAZHP_PDUMP_
46 #include "tng_trace.h"
47 #endif
48 #include <wsbm/wsbm_manager.h>
49
50 #include "hwdefs/topazhp_core_regs.h"
51 #include "hwdefs/topazhp_multicore_regs_old.h"
52 #include "hwdefs/topaz_db_regs.h"
53 #include "hwdefs/topaz_vlc_regs.h"
54 #include "hwdefs/mvea_regs.h"
55 #include "hwdefs/topazhp_default_params.h"
56
57 #define ALIGN_TO(value, align) ((value + align - 1) & ~(align - 1))
58 #define PAGE_ALIGN(value) ALIGN_TO(value, 4096)
59 #define DEFAULT_MVCALC_CONFIG ((0x00040303)|(MASK_TOPAZHP_CR_MVCALC_JITTER_POINTER_RST))
60 #define DEFAULT_MVCALC_COLOCATED (0x00100100)
61 #define MVEA_MV_PARAM_REGION_SIZE 16
62 #define MVEA_ABOVE_PARAM_REGION_SIZE 96
63 #define QUANT_LISTS_SIZE (224)
64 #define _1080P_30FPS (((1920*1088)/256)*30)
65 #define tng_align_64(X) (((X)+63) &~63)
66 #define tng_align_4(X) (((X)+3) &~3)
67
68 /* #define MTX_CONTEXT_ITEM_OFFSET(type, member) (size_t)&(((type*)0)->member) */
69
70 #define DEFAULT_CABAC_DB_MARGIN (0x190)
71 #define NOT_USED_BY_TOPAZ 0
72 /*
73 #define _TOPAZHP_CMDBUF_
74 */
75 #ifdef _TOPAZHP_CMDBUF_
tng__trace_cmdbuf_words(tng_cmdbuf_p cmdbuf)76 static void tng__trace_cmdbuf_words(tng_cmdbuf_p cmdbuf)
77 {
78 int i = 0;
79 IMG_UINT32 *ptmp = (IMG_UINT32 *)(cmdbuf->cmd_start);
80 IMG_UINT32 *pend = (IMG_UINT32 *)(cmdbuf->cmd_idx);
81 do {
82 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: command words [%d] = 0x%08x\n", __FUNCTION__, i++, (unsigned int)(*ptmp++));
83 } while(ptmp < pend);
84 return ;
85 }
86 #endif
87
88 #if 0
89 static IMG_UINT32 tng__get_codedbuffer_size(
90 IMG_STANDARD eStandard,
91 IMG_UINT16 ui16MBWidth,
92 IMG_UINT16 ui16MBHeight,
93 IMG_RC_PARAMS * psRCParams
94 )
95 {
96 if (eStandard == IMG_STANDARD_H264) {
97 // allocate based on worst case qp size
98 return ((IMG_UINT32)ui16MBWidth * (IMG_UINT32)ui16MBHeight * 400);
99 }
100
101 if (psRCParams->ui32InitialQp <= 5)
102 return ((IMG_UINT32)ui16MBWidth * (IMG_UINT32)ui16MBHeight * 1600);
103
104 return ((IMG_UINT32)ui16MBWidth * (IMG_UINT32)ui16MBHeight * 900);
105 }
106
107
108 static IMG_UINT32 tng__get_codedbuf_size_according_bitrate(
109 IMG_RC_PARAMS * psRCParams
110 )
111 {
112 return ((psRCParams->ui32BitsPerSecond + psRCParams->ui32FrameRate / 2) / psRCParams->ui32FrameRate) * 2;
113 }
114
115 static IMG_UINT32 tng__get_buffer_size(IMG_UINT32 src_size)
116 {
117 return (src_size + 0x1000) & (~0xfff);
118 }
119 #endif
120
121 //static inline
tng__alloc_init_buffer(psb_driver_data_p driver_data,unsigned int size,psb_buffer_type_t type,psb_buffer_p buf)122 VAStatus tng__alloc_init_buffer(
123 psb_driver_data_p driver_data,
124 unsigned int size,
125 psb_buffer_type_t type,
126 psb_buffer_p buf)
127 {
128 unsigned char *pch_virt_addr;
129 VAStatus vaStatus = VA_STATUS_SUCCESS;
130 vaStatus = psb_buffer_create(driver_data, size, type, buf);
131 if (VA_STATUS_SUCCESS != vaStatus) {
132 drv_debug_msg(VIDEO_DEBUG_ERROR, "alloc mem params buffer");
133 return vaStatus;
134 }
135
136 vaStatus = psb_buffer_map(buf, &pch_virt_addr);
137 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: phy addr 0x%08x, vir addr 0x%08x\n", __FUNCTION__, buf->drm_buf, pch_virt_addr);
138 if ((vaStatus) || (pch_virt_addr == NULL)) {
139 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: map buf 0x%08x\n", __FUNCTION__, (IMG_UINT32)pch_virt_addr);
140 psb_buffer_destroy(buf);
141 } else {
142 memset(pch_virt_addr, 0, size);
143 psb_buffer_unmap(buf);
144 }
145
146 return vaStatus;
147 }
148
tng__alloc_context_buffer(context_ENC_p ctx,IMG_UINT8 ui8IsJpeg,IMG_UINT32 ui32StreamID)149 static VAStatus tng__alloc_context_buffer(context_ENC_p ctx, IMG_UINT8 ui8IsJpeg, IMG_UINT32 ui32StreamID)
150 {
151 VAStatus vaStatus = VA_STATUS_SUCCESS;
152 IMG_UINT32 ui32_pic_width, ui32_pic_height;
153 IMG_UINT32 ui32_mb_per_row, ui32_mb_per_column;
154 IMG_UINT32 ui32_adj_mb_per_row = 0;
155 IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
156 psb_driver_data_p ps_driver_data = ctx->obj_context->driver_data;
157 context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamID]);
158 context_ENC_mem_size *ps_mem_size = &(ctx->ctx_mem_size);
159
160 if (ctx->eStandard == IMG_STANDARD_H264) {
161 ctx->ui8PipesToUse = tng__min(ctx->ui8PipesToUse, ctx->ui8SlicesPerPicture);
162 } else {
163 ctx->ui8PipesToUse = 1;
164 }
165
166 ctx->i32PicNodes = (psRCParams->b16Hierarchical ? MAX_REF_B_LEVELS : 0) + 4;
167 ctx->i32MVStores = (ctx->i32PicNodes * 2);
168 ctx->i32CodedBuffers = (IMG_INT32)(ctx->ui8PipesToUse) * (ctx->bIsInterlaced ? 3 : 2);
169 ctx->ui8SlotsInUse = psRCParams->ui16BFrames + 2;
170
171 if (0 != ui8IsJpeg) {
172 ctx->jpeg_pic_params_size = (sizeof(JPEG_MTX_QUANT_TABLE) + 0x3f) & (~0x3f);
173 ctx->jpeg_header_mem_size = (sizeof(JPEG_MTX_DMA_SETUP) + 0x3f) & (~0x3f);
174 ctx->jpeg_header_interface_mem_size = (sizeof(JPEG_MTX_WRITEBACK_MEMORY) + 0x3f) & (~0x3f);
175
176 //write back region
177 ps_mem_size->writeback = tng_align_KB(COMM_WB_DATA_BUF_SIZE);
178 tng__alloc_init_buffer(ps_driver_data, WB_FIFO_SIZE * ps_mem_size->writeback, psb_bt_cpu_vpu, &(ctx->bufs_writeback));
179
180 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: end\n", __FUNCTION__);
181 return vaStatus;
182 }
183
184 /* width and height should be source surface's w and h or ?? */
185 ui32_pic_width = ctx->obj_context->picture_width;
186 ui32_mb_per_row = (ctx->obj_context->picture_width + 15) >> 4;
187 ui32_pic_height = ctx->obj_context->picture_height;
188 ui32_mb_per_column = (ctx->obj_context->picture_height + 15) >> 4;
189 ui32_adj_mb_per_row = ((ui32_mb_per_row + 7)>>3)<<3; // Ensure multiple of 8 MBs per row
190
191 //command buffer use
192 ps_mem_size->pic_template = ps_mem_size->slice_template =
193 ps_mem_size->seq_header = tng_align_KB(TNG_HEADER_SIZE);
194 tng__alloc_init_buffer(ps_driver_data, ps_mem_size->seq_header,
195 psb_bt_cpu_vpu, &(ps_mem->bufs_seq_header));
196
197 if (ctx->bEnableMVC)
198 tng__alloc_init_buffer(ps_driver_data, ps_mem_size->seq_header,
199 psb_bt_cpu_vpu, &(ps_mem->bufs_sub_seq_header));
200
201 tng__alloc_init_buffer(ps_driver_data, 4 * ps_mem_size->pic_template,
202 psb_bt_cpu_vpu, &(ps_mem->bufs_pic_template));
203
204 tng__alloc_init_buffer(ps_driver_data, NUM_SLICE_TYPES * ps_mem_size->slice_template,
205 psb_bt_cpu_vpu, &(ps_mem->bufs_slice_template));
206
207 ps_mem_size->mtx_context = tng_align_KB(MTX_CONTEXT_SIZE);
208 tng__alloc_init_buffer(ps_driver_data, ps_mem_size->mtx_context,
209 psb_bt_cpu_vpu, &(ps_mem->bufs_mtx_context));
210
211 //sei header(AUDHeader+SEIBufferPeriodMem+SEIPictureTimingHeaderMem)
212 ps_mem_size->sei_header = tng_align_KB(64);
213 tng__alloc_init_buffer(ps_driver_data, 3 * ps_mem_size->sei_header,
214 psb_bt_cpu_vpu, &(ps_mem->bufs_sei_header));
215
216 //gop header
217 ps_mem_size->flat_gop = ps_mem_size->hierar_gop = tng_align_KB(64);
218 tng__alloc_init_buffer(ps_driver_data, ps_mem_size->flat_gop,
219 psb_bt_cpu_vpu, &(ps_mem->bufs_flat_gop));
220 tng__alloc_init_buffer(ps_driver_data, ps_mem_size->hierar_gop,
221 psb_bt_cpu_vpu, &(ps_mem->bufs_hierar_gop));
222
223 //above params
224 ps_mem_size->above_params = tng_align_KB(MVEA_ABOVE_PARAM_REGION_SIZE * tng_align_64(ui32_mb_per_row));
225 tng__alloc_init_buffer(ps_driver_data, (IMG_UINT32)(ctx->ui8PipesToUse) * ps_mem_size->above_params,
226 psb_bt_cpu_vpu, &(ps_mem->bufs_above_params));
227
228 //ctx->mv_setting_btable_size = tng_align_KB(MAX_BFRAMES * (tng_align_64(sizeof(IMG_MV_SETTINGS) * MAX_BFRAMES)));
229 ps_mem_size->mv_setting_btable = tng_align_KB(MAX_BFRAMES * MV_ROW_STRIDE);
230 tng__alloc_init_buffer(ps_driver_data, ps_mem_size->mv_setting_btable,
231 psb_bt_cpu_vpu, &(ps_mem->bufs_mv_setting_btable));
232
233 ps_mem_size->mv_setting_hierar = tng_align_KB(MAX_BFRAMES * sizeof(IMG_MV_SETTINGS));
234 tng__alloc_init_buffer(ps_driver_data, ps_mem_size->mv_setting_hierar,
235 psb_bt_cpu_vpu, &(ps_mem->bufs_mv_setting_hierar));
236
237 //colocated params
238 ps_mem_size->colocated = tng_align_KB(MVEA_MV_PARAM_REGION_SIZE * tng_align_4(ui32_mb_per_row * ui32_mb_per_column));
239 tng__alloc_init_buffer(ps_driver_data, ctx->i32PicNodes * ps_mem_size->colocated,
240 psb_bt_cpu_vpu, &(ps_mem->bufs_colocated));
241
242 ps_mem_size->interview_mv = ps_mem_size->mv = ps_mem_size->colocated;
243 tng__alloc_init_buffer(ps_driver_data, ctx->i32MVStores * ps_mem_size->mv,
244 psb_bt_cpu_vpu, &(ps_mem->bufs_mv));
245
246 if (ctx->bEnableMVC) {
247 tng__alloc_init_buffer(ps_driver_data, 2 * ps_mem_size->interview_mv,
248 psb_bt_cpu_vpu, &(ps_mem->bufs_interview_mv));
249 }
250
251 //write back region
252 ps_mem_size->writeback = tng_align_KB(COMM_WB_DATA_BUF_SIZE);
253 tng__alloc_init_buffer(ps_driver_data, WB_FIFO_SIZE * ps_mem_size->writeback,
254 psb_bt_cpu_vpu, &(ctx->bufs_writeback));
255
256 ps_mem_size->slice_map = tng_align_KB(0x1500); //(1 + MAX_SLICESPERPIC * 2 + 15) & ~15);
257 tng__alloc_init_buffer(ps_driver_data, ctx->ui8SlotsInUse * ps_mem_size->slice_map,
258 psb_bt_cpu_vpu, &(ps_mem->bufs_slice_map));
259
260 ps_mem_size->weighted_prediction = tng_align_KB(sizeof(WEIGHTED_PREDICTION_VALUES));
261 tng__alloc_init_buffer(ps_driver_data, ctx->ui8SlotsInUse * ps_mem_size->weighted_prediction,
262 psb_bt_cpu_vpu, &(ps_mem->bufs_weighted_prediction));
263
264 #ifdef LTREFHEADER
265 ps_mem_size->lt_ref_header = tng_align_KB((sizeof(MTX_HEADER_PARAMS)+63)&~63);
266 tng__alloc_init_buffer(ps_driver_data, ctx->ui8SlotsInUse * ps_mem_size->lt_ref_header,
267 psb_bt_cpu_vpu, &(ps_mem->bufs_lt_ref_header));
268 #endif
269
270 ps_mem_size->recon_pictures = tng_align_KB((tng_align_64(ui32_pic_width)*tng_align_64(ui32_pic_height))*3/2);
271 tng__alloc_init_buffer(ps_driver_data, ctx->i32PicNodes * ps_mem_size->recon_pictures,
272 psb_bt_cpu_vpu, &(ps_mem->bufs_recon_pictures));
273
274 ctx->ctx_mem_size.first_pass_out_params = tng_align_KB(sizeof(IMG_FIRST_STAGE_MB_PARAMS) * ui32_mb_per_row * ui32_mb_per_column);
275 tng__alloc_init_buffer(ps_driver_data, ctx->ui8SlotsInUse * ctx->ctx_mem_size.first_pass_out_params,
276 psb_bt_cpu_vpu, &(ps_mem->bufs_first_pass_out_params));
277
278 #ifndef EXCLUDE_BEST_MP_DECISION_DATA
279 ctx->ctx_mem_size.first_pass_out_best_multipass_param = tng_align_KB(ui32_mb_per_column * (((5*ui32_mb_per_row)+3)>>2) * 64);
280 tng__alloc_init_buffer(ps_driver_data, ctx->ui8SlotsInUse * ctx->ctx_mem_size.first_pass_out_best_multipass_param,
281 psb_bt_cpu_vpu, &(ps_mem->bufs_first_pass_out_best_multipass_param));
282 #endif
283
284 ctx->ctx_mem_size.mb_ctrl_in_params = tng_align_KB(sizeof(IMG_FIRST_STAGE_MB_PARAMS) * ui32_adj_mb_per_row * ui32_mb_per_column);
285 tng__alloc_init_buffer(ps_driver_data, ctx->ui8SlotsInUse * ctx->ctx_mem_size.mb_ctrl_in_params,
286 psb_bt_cpu_vpu, &(ps_mem->bufs_mb_ctrl_in_params));
287
288 ctx->ctx_mem_size.lowpower_params = tng_align_KB(TNG_HEADER_SIZE);
289 tng__alloc_init_buffer(ps_driver_data, ps_mem_size->lowpower_params,
290 psb_bt_cpu_vpu, &(ps_mem->bufs_lowpower_params));
291
292 ctx->ctx_mem_size.lowpower_data = tng_align_KB(0x10000);
293
294 return vaStatus;
295 }
296
tng__free_context_buffer(context_ENC_p ctx,unsigned char is_JPEG,unsigned int stream_id)297 static void tng__free_context_buffer(context_ENC_p ctx, unsigned char is_JPEG, unsigned int stream_id)
298 {
299 context_ENC_mem *ps_mem = &(ctx->ctx_mem[stream_id]);
300
301 if (0 != is_JPEG) {
302 psb_buffer_destroy(&(ctx->bufs_writeback));
303 return;
304 }
305 psb_buffer_destroy(&(ps_mem->bufs_seq_header));
306 if (ctx->bEnableMVC)
307 psb_buffer_destroy(&(ps_mem->bufs_sub_seq_header));
308 psb_buffer_destroy(&(ps_mem->bufs_pic_template));
309 psb_buffer_destroy(&(ps_mem->bufs_slice_template));
310 psb_buffer_destroy(&(ps_mem->bufs_mtx_context));
311 psb_buffer_destroy(&(ps_mem->bufs_sei_header));
312
313 psb_buffer_destroy(&(ps_mem->bufs_flat_gop));
314 psb_buffer_destroy(&(ps_mem->bufs_hierar_gop));
315 psb_buffer_destroy(&(ps_mem->bufs_above_params));
316 psb_buffer_destroy(&(ps_mem->bufs_mv_setting_btable));
317 psb_buffer_destroy(&(ps_mem->bufs_mv_setting_hierar));
318 psb_buffer_destroy(&(ps_mem->bufs_colocated));
319 psb_buffer_destroy(&(ps_mem->bufs_mv));
320 if (ctx->bEnableMVC)
321 psb_buffer_destroy(&(ps_mem->bufs_interview_mv));
322
323 psb_buffer_destroy(&(ctx->bufs_writeback));
324 psb_buffer_destroy(&(ps_mem->bufs_slice_map));
325 psb_buffer_destroy(&(ps_mem->bufs_weighted_prediction));
326 #ifdef LTREFHEADER
327 psb_buffer_destroy(&(ps_mem->bufs_lt_ref_header));
328 #endif
329 psb_buffer_destroy(&(ps_mem->bufs_recon_pictures));
330 psb_buffer_destroy(&(ps_mem->bufs_first_pass_out_params));
331 #ifndef EXCLUDE_BEST_MP_DECISION_DATA
332 psb_buffer_destroy(&(ps_mem->bufs_first_pass_out_best_multipass_param));
333 #endif
334 psb_buffer_destroy(&(ps_mem->bufs_mb_ctrl_in_params));
335 psb_buffer_destroy(&(ps_mem->bufs_lowpower_params));
336
337 return ;
338 }
339
tng__get_ipe_control(IMG_CODEC eEncodingFormat)340 unsigned int tng__get_ipe_control(IMG_CODEC eEncodingFormat)
341 {
342 unsigned int RegVal = 0;
343
344 RegVal = F_ENCODE(2, MVEA_CR_IPE_GRID_FINE_SEARCH) |
345 F_ENCODE(0, MVEA_CR_IPE_GRID_SEARCH_SIZE) |
346 F_ENCODE(1, MVEA_CR_IPE_Y_FINE_SEARCH);
347
348 switch (eEncodingFormat) {
349 case IMG_CODEC_H263_NO_RC:
350 case IMG_CODEC_H263_VBR:
351 case IMG_CODEC_H263_CBR:
352 RegVal |= F_ENCODE(0, MVEA_CR_IPE_BLOCKSIZE) | F_ENCODE(0, MVEA_CR_IPE_ENCODING_FORMAT);
353 break;
354 case IMG_CODEC_MPEG4_NO_RC:
355 case IMG_CODEC_MPEG4_VBR:
356 case IMG_CODEC_MPEG4_CBR:
357 RegVal |= F_ENCODE(1, MVEA_CR_IPE_BLOCKSIZE) | F_ENCODE(1, MVEA_CR_IPE_ENCODING_FORMAT);
358 default:
359 break;
360 case IMG_CODEC_H264_NO_RC:
361 case IMG_CODEC_H264_VBR:
362 case IMG_CODEC_H264_CBR:
363 case IMG_CODEC_H264_VCM:
364 RegVal |= F_ENCODE(2, MVEA_CR_IPE_BLOCKSIZE) | F_ENCODE(2, MVEA_CR_IPE_ENCODING_FORMAT);
365 break;
366 }
367 RegVal |= F_ENCODE(6, MVEA_CR_IPE_Y_CANDIDATE_NUM);
368 return RegVal;
369 }
370
tng__setup_enc_profile_features(context_ENC_p ctx,IMG_UINT32 ui32EncProfile)371 void tng__setup_enc_profile_features(context_ENC_p ctx, IMG_UINT32 ui32EncProfile)
372 {
373 IMG_ENCODE_FEATURES * pEncFeatures = &ctx->sEncFeatures;
374 /* Set the default values first */
375 pEncFeatures->bDisableBPicRef_0 = IMG_FALSE;
376 pEncFeatures->bDisableBPicRef_1 = IMG_FALSE;
377
378 pEncFeatures->bDisableInter8x8 = IMG_FALSE;
379 pEncFeatures->bRestrictInter4x4 = IMG_FALSE;
380
381 pEncFeatures->bDisableIntra4x4 = IMG_FALSE;
382 pEncFeatures->bDisableIntra8x8 = IMG_FALSE;
383 pEncFeatures->bDisableIntra16x16 = IMG_FALSE;
384
385 pEncFeatures->bEnable8x16MVDetect = IMG_TRUE;
386 pEncFeatures->bEnable16x8MVDetect = IMG_TRUE;
387 pEncFeatures->bDisableBFrames = IMG_FALSE;
388
389 pEncFeatures->eMinBlkSz = BLK_SZ_DEFAULT;
390
391 switch (ui32EncProfile) {
392 case ENC_PROFILE_LOWCOMPLEXITY:
393 pEncFeatures->bDisableInter8x8 = IMG_TRUE;
394 pEncFeatures->bRestrictInter4x4 = IMG_TRUE;
395 pEncFeatures->bDisableIntra4x4 = IMG_TRUE;
396 pEncFeatures->bDisableIntra8x8 = IMG_TRUE;
397 pEncFeatures->bRestrictInter4x4 = IMG_TRUE;
398 pEncFeatures->eMinBlkSz = BLK_SZ_16x16;
399 pEncFeatures->bDisableBFrames = IMG_TRUE;
400 break;
401
402 case ENC_PROFILE_HIGHCOMPLEXITY:
403 pEncFeatures->bDisableBPicRef_0 = IMG_FALSE;
404 pEncFeatures->bDisableBPicRef_1 = IMG_FALSE;
405
406 pEncFeatures->bDisableInter8x8 = IMG_FALSE;
407 pEncFeatures->bRestrictInter4x4 = IMG_FALSE;
408
409 pEncFeatures->bDisableIntra4x4 = IMG_FALSE;
410 pEncFeatures->bDisableIntra8x8 = IMG_FALSE;
411 pEncFeatures->bDisableIntra16x16 = IMG_FALSE;
412
413 pEncFeatures->bEnable8x16MVDetect = IMG_TRUE;
414 pEncFeatures->bEnable16x8MVDetect = IMG_TRUE;
415 break;
416 }
417
418 if (ctx->eStandard != IMG_STANDARD_H264) {
419 pEncFeatures->bEnable8x16MVDetect = IMG_FALSE;
420 pEncFeatures->bEnable16x8MVDetect = IMG_FALSE;
421 }
422
423 return;
424 }
425
tng__patch_hw_profile(context_ENC_p ctx)426 VAStatus tng__patch_hw_profile(context_ENC_p ctx)
427 {
428 IMG_UINT32 ui32IPEControl = 0;
429 IMG_UINT32 ui32PredCombControl = 0;
430 IMG_ENCODE_FEATURES * psEncFeatures = &(ctx->sEncFeatures);
431
432 // bDisableIntra4x4
433 if (psEncFeatures->bDisableIntra4x4)
434 ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTRA4X4_DISABLE);
435
436 //bDisableIntra8x8
437 if (psEncFeatures->bDisableIntra8x8)
438 ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTRA8X8_DISABLE);
439
440 //bDisableIntra16x16, check if atleast one of the other Intra mode is enabled
441 if ((psEncFeatures->bDisableIntra16x16) &&
442 (!(psEncFeatures->bDisableIntra8x8) || !(psEncFeatures->bDisableIntra4x4))) {
443 ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTRA16X16_DISABLE);
444 }
445
446 if (psEncFeatures->bRestrictInter4x4) {
447 // ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTER4X4_RESTRICT);
448 ui32IPEControl |= F_ENCODE(1, TOPAZHP_CR_IPE_MV_NUMBER_RESTRICTION);
449 }
450
451 if (psEncFeatures->bDisableInter8x8)
452 ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTER8X8_DISABLE);
453
454 if (psEncFeatures->bDisableBPicRef_1)
455 ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_B_PIC1_DISABLE);
456 else if (psEncFeatures->bDisableBPicRef_0)
457 ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_B_PIC0_DISABLE);
458
459 // save predictor combiner control in video encode parameter set
460 ctx->ui32PredCombControl = ui32PredCombControl;
461
462 // set blocksize
463 ui32IPEControl |= F_ENCODE(psEncFeatures->eMinBlkSz, TOPAZHP_CR_IPE_BLOCKSIZE);
464
465 if (psEncFeatures->bEnable8x16MVDetect)
466 ui32IPEControl |= F_ENCODE(1, TOPAZHP_CR_IPE_8X16_ENABLE);
467
468 if (psEncFeatures->bEnable16x8MVDetect)
469 ui32IPEControl |= F_ENCODE(1, TOPAZHP_CR_IPE_16X8_ENABLE);
470
471 if (psEncFeatures->bDisableBFrames)
472 ctx->sRCParams.ui16BFrames = 0;
473
474 //save IPE-control register
475 ctx->ui32IPEControl = ui32IPEControl;
476
477 return VA_STATUS_SUCCESS;
478 }
479
480 #ifdef _TOPAZHP_CMDBUF_
tng__trace_cmdbuf(tng_cmdbuf_p cmdbuf,int idx)481 static void tng__trace_cmdbuf(tng_cmdbuf_p cmdbuf, int idx)
482 {
483 IMG_UINT32 ui32CmdTmp[4];
484 IMG_UINT32 *ptmp = (IMG_UINT32 *)(cmdbuf->cmd_start);
485 IMG_UINT32 *pend = (IMG_UINT32 *)(cmdbuf->cmd_idx);
486 IMG_UINT32 ui32Len;
487
488 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: start, stream (%d), ptmp (0x%08x), pend (0x%08x}\n", __FUNCTION__, idx, (unsigned int)ptmp, (unsigned int)pend);
489
490 if (idx)
491 return ;
492
493 while (ptmp < pend) {
494 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: ptmp (0x%08x}\n", __FUNCTION__, *ptmp);
495 if ((*ptmp & 0x7f) == MTX_CMDID_SW_NEW_CODEC) {
496 ptmp += 4;
497 } else if ((*ptmp & 0x7f) == MTX_CMDID_SW_LEAVE_LOWPOWER) {
498 ptmp += 2;
499 } else if ((*ptmp & 0x7f) == MTX_CMDID_SW_WRITEREG) {
500 ui32Len = *(++ptmp);
501 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: len = %d\n", __FUNCTION__, ui32Len);
502 ptmp += (ui32Len * 3) + 1;
503 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: reg ptmp (0x%08x}\n", __FUNCTION__, *ptmp);
504 } else if ((*ptmp & 0x7f) == MTX_CMDID_DO_HEADER) {
505 ui32CmdTmp[0] = *ptmp++;
506 ui32CmdTmp[1] = *ptmp++;
507 ui32CmdTmp[2] = *ptmp++;
508 ui32CmdTmp[3] = 0;
509 //topazhp_dump_command((unsigned int*)ui32CmdTmp);
510 ptmp += 2;
511 } else if (
512 ((*ptmp & 0x7f) == MTX_CMDID_SETVIDEO)||
513 ((*ptmp & 0x7f) == MTX_CMDID_SHUTDOWN)) {
514 ui32CmdTmp[0] = *ptmp++;
515 ui32CmdTmp[1] = *ptmp++;
516 ui32CmdTmp[2] = *ptmp++;
517 ui32CmdTmp[3] = *ptmp++;
518 //topazhp_dump_command((unsigned int*)ui32CmdTmp);
519 } else if (
520 ((*ptmp & 0x7f) == MTX_CMDID_PROVIDE_SOURCE_BUFFER) ||
521 ((*ptmp & 0x7f) == MTX_CMDID_PROVIDE_REF_BUFFER) ||
522 ((*ptmp & 0x7f) == MTX_CMDID_PROVIDE_CODED_BUFFER) ||
523 ((*ptmp & 0x7f) == MTX_CMDID_PICMGMT) ||
524 ((*ptmp & 0x7f) == MTX_CMDID_ENCODE_FRAME)) {
525 ui32CmdTmp[0] = *ptmp++;
526 ui32CmdTmp[1] = *ptmp++;
527 ui32CmdTmp[2] = *ptmp++;
528 ui32CmdTmp[3] = 0;
529 //topazhp_dump_command((unsigned int*)ui32CmdTmp);
530 } else {
531 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: error leave lowpower = 0x%08x\n", __FUNCTION__, *ptmp++);
532 }
533 }
534
535 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: end\n", __FUNCTION__);
536
537 return ;
538 }
539 #endif
540
tng_DestroyContext(object_context_p obj_context,unsigned char is_JPEG)541 void tng_DestroyContext(object_context_p obj_context, unsigned char is_JPEG)
542 {
543 context_ENC_p ctx;
544 // tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
545 ctx = (context_ENC_p)obj_context->format_data;
546 FRAME_ORDER_INFO *psFrameInfo = &(ctx->sFrameOrderInfo);
547
548 if (psFrameInfo->slot_consume_dpy_order != NULL)
549 free(psFrameInfo->slot_consume_dpy_order);
550 if (psFrameInfo->slot_consume_enc_order != NULL)
551 free(psFrameInfo->slot_consume_enc_order);
552
553 tng_air_buf_free(ctx);
554
555 tng__free_context_buffer(ctx, is_JPEG, 0);
556
557 if (ctx->bEnableMVC)
558 tng__free_context_buffer(ctx, is_JPEG, 1);
559
560 free(obj_context->format_data);
561 obj_context->format_data = NULL;
562 }
563
tng__init_rc_params(context_ENC_p ctx,object_config_p obj_config)564 static VAStatus tng__init_rc_params(context_ENC_p ctx, object_config_p obj_config)
565 {
566 IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
567 unsigned int eRCmode = 0;
568 memset(psRCParams, 0, sizeof(IMG_RC_PARAMS));
569 IMG_INT32 i;
570
571 //set RC mode
572 for (i = 0; i < obj_config->attrib_count; i++) {
573 if (obj_config->attrib_list[i].type == VAConfigAttribRateControl)
574 break;
575 }
576
577 if (i >= obj_config->attrib_count) {
578 eRCmode = VA_RC_NONE;
579 } else {
580 eRCmode = obj_config->attrib_list[i].value;
581 }
582
583 ctx->sRCParams.bRCEnable = IMG_TRUE;
584 ctx->sRCParams.bDisableBitStuffing = IMG_FALSE;
585
586 if (eRCmode == VA_RC_NONE) {
587 ctx->sRCParams.bRCEnable = IMG_FALSE;
588 ctx->sRCParams.eRCMode = IMG_RCMODE_NONE;
589 } else if (eRCmode == VA_RC_CBR) {
590 ctx->sRCParams.eRCMode = IMG_RCMODE_CBR;
591 } else if (eRCmode == VA_RC_VBR) {
592 ctx->sRCParams.eRCMode = IMG_RCMODE_VBR;
593 } else if (eRCmode == VA_RC_VCM) {
594 ctx->sRCParams.eRCMode = IMG_RCMODE_VCM;
595 } else {
596 ctx->sRCParams.bRCEnable = IMG_FALSE;
597 drv_debug_msg(VIDEO_DEBUG_ERROR, "not support this RT Format\n");
598 return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
599 }
600
601 psRCParams->bScDetectDisable = IMG_FALSE;
602 psRCParams->ui32SliceByteLimit = 0;
603 psRCParams->ui32SliceMBLimit = 0;
604 psRCParams->bIsH264Codec = (ctx->eStandard == IMG_STANDARD_H264) ? IMG_TRUE : IMG_FALSE;
605 return VA_STATUS_SUCCESS;
606 }
607
608 /**************************************************************************************************
609 * Function: IMG_C_GetEncoderCaps
610 * Description: Get the capabilities of the encoder for the given codec
611 *
612 ***************************************************************************************************/
613 //FIXME
614 static const IMG_UINT32 g_ui32PipesAvailable = TOPAZHP_PIPE_NUM;
615 static const IMG_UINT32 g_ui32CoreDes1 = TOPAZHP_PIPE_NUM;
616 static const IMG_UINT32 g_ui32CoreRev = 0x00030401;
617
tng__get_num_pipes()618 static IMG_UINT32 tng__get_num_pipes()
619 {
620 return g_ui32PipesAvailable;
621 }
622
tng__get_core_des1()623 static IMG_UINT32 tng__get_core_des1()
624 {
625 return g_ui32CoreDes1;
626 }
627
tng__get_core_rev()628 static IMG_UINT32 tng__get_core_rev()
629 {
630 return g_ui32CoreRev;
631 }
632
tng__get_encoder_caps(context_ENC_p ctx)633 static VAStatus tng__get_encoder_caps(context_ENC_p ctx)
634 {
635 IMG_ENC_CAPS *psCaps = &(ctx->sCapsParams);
636 IMG_UINT16 ui16Height = ctx->ui16FrameHeight;
637 IMG_UINT32 ui32NumCores = 0;
638 IMG_UINT16 ui16MBRows = 0; //MB Rows in a GOB(slice);
639
640 ctx->ui32CoreRev = tng__get_core_rev();
641 psCaps->ui32CoreFeatures = tng__get_core_des1();
642
643 /* get the actual number of cores */
644 ui32NumCores = tng__get_num_pipes();
645
646 switch (ctx->eStandard) {
647 case IMG_STANDARD_JPEG:
648 psCaps->ui16MaxSlices = ui16Height / 8;
649 psCaps->ui16MinSlices = 1;
650 psCaps->ui16RecommendedSlices = ui32NumCores;
651 break;
652 case IMG_STANDARD_H264:
653 psCaps->ui16MaxSlices = ui16Height / 16;
654 psCaps->ui16MinSlices = 1;
655 psCaps->ui16RecommendedSlices = ui32NumCores;
656 break;
657 case IMG_STANDARD_MPEG2:
658 psCaps->ui16MaxSlices = 174; // Slice labelling dictates a maximum of 174 slices
659 psCaps->ui16MinSlices = 1;
660 psCaps->ui16RecommendedSlices = (ui16Height + 15) / 16;
661 break;
662 case IMG_STANDARD_H263:
663 // if the original height of the pic is less than 400 , k is 1. refer standard.
664 if (ui16Height <= 400) {
665 ui16MBRows = 1;
666 } else if (ui16Height < 800) { // if between 400 and 800 it's 2.
667 ui16MBRows = 2;
668 } else {
669 ui16MBRows = 4;
670 }
671 // before rounding is done for the height.
672 // get the GOB's based on this MB Rows and not vice-versa.
673 psCaps->ui16RecommendedSlices = (ui16Height + 15) >> (4 + (ui16MBRows >> 1));
674 psCaps->ui16MaxSlices = psCaps->ui16MinSlices = psCaps->ui16RecommendedSlices;
675 break;
676 case IMG_STANDARD_MPEG4:
677 psCaps->ui16MaxSlices = 1;
678 psCaps->ui16MinSlices = 1;
679 psCaps->ui16RecommendedSlices = 1;
680 break;
681 default:
682 break;
683 }
684 return VA_STATUS_SUCCESS;
685 }
686
tng__init_context(context_ENC_p ctx)687 static VAStatus tng__init_context(context_ENC_p ctx)
688 {
689 VAStatus vaStatus = 0;
690
691 /* Mostly sure about the following video parameters */
692 //ctx->ui32HWProfile = pParams->ui32HWProfile;
693 ctx->ui32FrameCount[0] = ctx->ui32FrameCount[1] = 0;
694 /* Using Extended parameters */
695 ctx->ui8PipesToUse = (IMG_UINT8)(tng__get_num_pipes() & (IMG_UINT32)0xff);
696 //carc params
697 ctx->sCARCParams.bCARC = 0;
698 ctx->sCARCParams.i32CARCBaseline = 0;
699 ctx->sCARCParams.ui32CARCThreshold = TOPAZHP_DEFAULT_uCARCThreshold;
700 ctx->sCARCParams.ui32CARCCutoff = TOPAZHP_DEFAULT_uCARCCutoff;
701 ctx->sCARCParams.ui32CARCNegRange = TOPAZHP_DEFAULT_uCARCNegRange;
702 ctx->sCARCParams.ui32CARCNegScale = TOPAZHP_DEFAULT_uCARCNegScale;
703 ctx->sCARCParams.ui32CARCPosRange = TOPAZHP_DEFAULT_uCARCPosRange;
704 ctx->sCARCParams.ui32CARCPosScale = TOPAZHP_DEFAULT_uCARCPosScale;
705 ctx->sCARCParams.ui32CARCShift = TOPAZHP_DEFAULT_uCARCShift;
706
707 ctx->bUseDefaultScalingList = IMG_FALSE;
708 ctx->ui32CabacBinLimit = TOPAZHP_DEFAULT_uCABACBinLimit; //This parameter need not be exposed
709 if (ctx->ui32CabacBinLimit == 0)
710 ctx->ui32CabacBinFlex = 0;//This parameter need not be exposed
711 else
712 ctx->ui32CabacBinFlex = TOPAZHP_DEFAULT_uCABACBinFlex;//This parameter need not be exposed
713
714 ctx->ui32FCode = 4; //This parameter need not be exposed
715 ctx->iFineYSearchSize = 2;//This parameter need not be exposed
716 ctx->ui32VopTimeResolution = 15;//This parameter need not be exposed
717 // ctx->bEnabledDynamicBPic = IMG_FALSE;//Related to Rate Control,which is no longer needed.
718 ctx->bH264IntraConstrained = IMG_FALSE;//This parameter need not be exposed
719 ctx->bEnableInpCtrl = IMG_FALSE;//This parameter need not be exposed
720 ctx->bEnableAIR = 0;
721 ctx->bEnableCIR = 0;
722 ctx->bEnableHostBias = (ctx->bEnableAIR != 0);//This parameter need not be exposed
723 ctx->bEnableHostQP = IMG_FALSE; //This parameter need not be exposed
724 ctx->ui8CodedSkippedIndex = 3;//This parameter need not be exposed
725 ctx->ui8InterIntraIndex = 3;//This parameter need not be exposed
726 ctx->uMaxChunks = 0xA0;//This parameter need not be exposed
727 ctx->uChunksPerMb = 0x40;//This parameter need not be exposed
728 ctx->uPriorityChunks = (0xA0 - 0x60);//This parameter need not be exposed
729 ctx->bWeightedPrediction = IMG_FALSE;//Weighted Prediction is not supported in TopazHP Version 3.0
730 ctx->ui8VPWeightedImplicitBiPred = 0;//Weighted Prediction is not supported in TopazHP Version 3.0
731 ctx->bSkipDuplicateVectors = IMG_FALSE;//By default false Newly Added
732 ctx->bEnableCumulativeBiases = IMG_FALSE;//By default false Newly Added
733 ctx->ui16UseCustomScalingLists = 0;//By default false Newly Added
734 ctx->bPpsScaling = IMG_FALSE;//By default false Newly Added
735 ctx->ui8MPEG2IntraDCPrecision = 0;//By default 0 Newly Added
736 ctx->uMBspS = 0;//By default 0 Newly Added
737 ctx->bMultiReferenceP = IMG_FALSE;//By default false Newly Added
738 ctx->ui8RefSpacing=0;//By default 0 Newly Added
739 ctx->bSpatialDirect = 0;//By default 0 Newly Added
740 ctx->ui32DebugCRCs = 0;//By default false Newly Added
741 ctx->bEnableMVC = IMG_FALSE;//By default false Newly Added
742 ctx->ui16MVCViewIdx = (IMG_UINT16)(NON_MVC_VIEW);//Newly Added
743 ctx->bSrcAllocInternally = IMG_FALSE;//By default false Newly Added
744 ctx->bCodedAllocInternally = IMG_FALSE;//By default true Newly Added
745 ctx->bHighLatency = IMG_TRUE;//Newly Added
746 ctx->i32NumAIRMBs = -1;
747 ctx->i32AIRThreshold = -1;
748 ctx->i16AIRSkipCnt = -1;
749 ctx->i32LastCIRIndex = -1;
750 //Need to check on the following parameters
751 ctx->ui8EnableSelStatsFlags = IMG_FALSE;//Default Value ?? Extended Parameter ??
752 ctx->bH2648x8Transform = IMG_FALSE;//Default Value ?? Extended Parameter or OMX_VIDEO_PARAM_AVCTYPE -> bDirect8x8Inference??
753 //FIXME: Zhaohan, eStandard is always 0 here.
754 ctx->bNoOffscreenMv = (ctx->eStandard == IMG_STANDARD_H263) ? IMG_TRUE : IMG_FALSE; //Default Value ?? Extended Parameter and bUseOffScreenMVUserSetting
755 ctx->bNoSequenceHeaders = IMG_FALSE;
756 ctx->bTopFieldFirst = IMG_TRUE;
757 ctx->sBiasTables.ui32FCode = ctx->ui32FCode;
758 ctx->ui32pseudo_rand_seed = UNINIT_PARAM;
759 ctx->bVPAdaptiveRoundingDisable = IMG_TRUE;
760
761 //Default fcode is 4
762 if (!ctx->sBiasTables.ui32FCode)
763 ctx->sBiasTables.ui32FCode = 4;
764
765 ctx->uiCbrBufferTenths = TOPAZHP_DEFAULT_uiCbrBufferTenths;
766
767 tng__setup_enc_profile_features(ctx, ENC_PROFILE_DEFAULT);
768
769 vaStatus = tng__patch_hw_profile(ctx);
770 if (vaStatus != VA_STATUS_SUCCESS) {
771 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: tng__patch_hw_profile\n", __FUNCTION__);
772 }
773
774 return VA_STATUS_SUCCESS;
775 }
776
tng_CreateContext(object_context_p obj_context,object_config_p obj_config,unsigned char is_JPEG)777 VAStatus tng_CreateContext(
778 object_context_p obj_context,
779 object_config_p obj_config,
780 unsigned char is_JPEG)
781 {
782 VAStatus vaStatus = 0;
783 unsigned short ui16Width, ui16Height;
784 context_ENC_p ctx;
785
786 ui16Width = obj_context->picture_width;
787 ui16Height = obj_context->picture_height;
788 ctx = (context_ENC_p) calloc(1, sizeof(struct context_ENC_s));
789 if (NULL == ctx) {
790 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
791 DEBUG_FAILURE;
792 return vaStatus;
793 }
794
795 memset((void*)ctx, 0, sizeof(struct context_ENC_s));
796
797 obj_context->format_data = (void*) ctx;
798 ctx->obj_context = obj_context;
799
800 if (is_JPEG == 0) {
801 ctx->ui16Width = (unsigned short)(~0xf & (ui16Width + 0xf));
802 ctx->ui16FrameHeight = (unsigned short)(~0xf & (ui16Height + 0xf));
803
804 vaStatus = tng__init_context(ctx);
805 if (vaStatus != VA_STATUS_SUCCESS) {
806 drv_debug_msg(VIDEO_DEBUG_ERROR, "init Context params");
807 }
808
809 vaStatus = tng__init_rc_params(ctx, obj_config);
810 if (vaStatus != VA_STATUS_SUCCESS) {
811 drv_debug_msg(VIDEO_DEBUG_ERROR, "init rc params");
812 }
813 } else {
814 /*JPEG only require them are even*/
815 ctx->ui16Width = (unsigned short)(~0x1 & (ui16Width + 0x1));
816 ctx->ui16FrameHeight = (unsigned short)(~0x1 & (ui16Height + 0x1));
817 }
818
819 ctx->eFormat = IMG_CODEC_PL12; // use default
820
821 tng__setup_enc_profile_features(ctx, ENC_PROFILE_DEFAULT);
822
823 if (is_JPEG) {
824 vaStatus = tng__alloc_context_buffer(ctx, is_JPEG, 0);
825 if (vaStatus != VA_STATUS_SUCCESS) {
826 drv_debug_msg(VIDEO_DEBUG_ERROR, "setup enc profile");
827 }
828 }
829
830 return vaStatus;
831 }
832
tng_BeginPicture(context_ENC_p ctx)833 VAStatus tng_BeginPicture(context_ENC_p ctx)
834 {
835 VAStatus vaStatus = VA_STATUS_SUCCESS;
836 context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
837 tng_cmdbuf_p cmdbuf;
838 int ret;
839
840 ctx->ui32StreamID = 0;
841
842 if (ctx->ui32RawFrameCount != 0)
843 ps_buf->previous_src_surface = ps_buf->src_surface;
844 ps_buf->src_surface = ctx->obj_context->current_render_target;
845
846 vaStatus = tng__get_encoder_caps(ctx);
847 if (vaStatus != VA_STATUS_SUCCESS) {
848 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: tng__get_encoder_caps\n", __FUNCTION__);
849 }
850
851 /* clear frameskip flag to 0 */
852 CLEAR_SURFACE_INFO_skipped_flag(ps_buf->src_surface->psb_surface);
853
854 /* Initialise the command buffer */
855 ret = tng_context_get_next_cmdbuf(ctx->obj_context);
856 if (ret) {
857 drv_debug_msg(VIDEO_DEBUG_ERROR, "get next cmdbuf fail\n");
858 vaStatus = VA_STATUS_ERROR_UNKNOWN;
859 return vaStatus;
860 }
861 cmdbuf = ctx->obj_context->tng_cmdbuf;
862
863 //FIXME
864 /* only map topaz param when necessary */
865 cmdbuf->topaz_in_params_I_p = NULL;
866 cmdbuf->topaz_in_params_P_p = NULL;
867 ctx->obj_context->slice_count = 0;
868
869 tng_cmdbuf_buffer_ref(cmdbuf, &(ctx->obj_context->current_render_target->psb_surface->buf));
870
871 return vaStatus;
872 }
873
tng__provide_buffer_BFrames(context_ENC_p ctx,IMG_UINT32 ui32StreamIndex)874 static VAStatus tng__provide_buffer_BFrames(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
875 {
876 IMG_RC_PARAMS * psRCParams = &(ctx->sRCParams);
877 FRAME_ORDER_INFO *psFrameInfo = &(ctx->sFrameOrderInfo);
878 int slot_index = 0;
879 unsigned long long display_order = 0;
880 IMG_INT32 i32SlotBuf = (IMG_INT32)(psRCParams->ui16BFrames + 2);
881 IMG_UINT32 ui32SlotBuf = (IMG_UINT32)(psRCParams->ui16BFrames + 2);
882 IMG_UINT32 ui32FrameIdx = ctx->ui32FrameCount[ui32StreamIndex];
883
884 if (ui32StreamIndex == 0)
885 getFrameDpyOrder(ui32FrameIdx, psRCParams->ui16BFrames, ctx->ui32IntraCnt,
886 ctx->ui32IdrPeriod, psFrameInfo, &display_order);
887
888 slot_index = psFrameInfo->last_slot;
889
890 drv_debug_msg(VIDEO_DEBUG_GENERAL,
891 "%s: (int)ui32FrameIdx = %d, psRCParams->ui16BFrames = %d, psRCParams->ui32IntraFreq = %d, ctx->ui32IdrPeriod = %d\n",
892 __FUNCTION__, (int)ui32FrameIdx, (int)psRCParams->ui16BFrames, (int)psRCParams->ui32IntraFreq, ctx->ui32IdrPeriod);
893
894 drv_debug_msg(VIDEO_DEBUG_GENERAL,
895 "%s: last_slot = %d, last_frame_type = %d, display_order = %d\n",
896 __FUNCTION__, psFrameInfo->last_slot, psFrameInfo->last_frame_type, display_order);
897
898 if (ui32FrameIdx < ui32SlotBuf) {
899 if (ui32FrameIdx == 0) {
900 tng_send_source_frame(ctx, 0, 0);
901 } else if (ui32FrameIdx == 1) {
902 slot_index = 1;
903 do {
904 tng_send_source_frame(ctx, slot_index, slot_index);
905 ++slot_index;
906 } while(slot_index < i32SlotBuf);
907 } else {
908 slot_index = ui32FrameIdx - 1;
909 tng_send_source_frame(ctx, slot_index, slot_index);
910 }
911 } else {
912 tng_send_source_frame(ctx, slot_index , display_order);
913 }
914
915 return VA_STATUS_SUCCESS;
916 }
917
tng__provide_buffer_PFrames(context_ENC_p ctx,IMG_UINT32 ui32StreamIndex)918 VAStatus tng__provide_buffer_PFrames(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
919 {
920 IMG_UINT32 ui32FrameIdx = ctx->ui32FrameCount[ui32StreamIndex];
921
922 drv_debug_msg(VIDEO_DEBUG_GENERAL,
923 "%s: frame count = %d, SlotsInUse = %d, ui32FrameIdx = %d\n",
924 __FUNCTION__, (int)ui32FrameIdx, ctx->ui8SlotsInUse, ui32FrameIdx);
925
926 tng_send_source_frame(ctx, ctx->ui8SlotsCoded, ui32FrameIdx);
927 /*
928 if (ctx->ui32IntraCnt == 0)
929 ctx->eFrameType = IMG_INTRA_FRAME;
930 else
931 if (ui32FrameIdx % ctx->ui32IntraCnt == 0)
932 ctx->eFrameType = IMG_INTRA_FRAME;
933 else
934 ctx->eFrameType = IMG_INTER_P;
935
936 if (ctx->ui32IdrPeriod == 0) {
937 if (ui32FrameIdx == 0)
938 ctx->eFrameType = IMG_INTRA_IDR;
939 } else {
940 if (ctx->ui32IntraCnt == 0) {
941 if (ui32FrameIdx % ctx->ui32IdrPeriod == 0)
942 ctx->eFrameType = IMG_INTRA_IDR;
943 } else {
944 if (ui32FrameIdx % (ctx->ui32IntraCnt * ctx->ui32IdrPeriod) == 0)
945 ctx->eFrameType = IMG_INTRA_IDR;
946 }
947 }
948 */
949 ctx->eFrameType = IMG_INTER_P;
950
951 if (ui32FrameIdx % ctx->ui32IntraCnt == 0)
952 ctx->eFrameType = IMG_INTRA_FRAME;
953
954 if (ui32FrameIdx % (ctx->ui32IdrPeriod * ctx->ui32IntraCnt) == 0)
955 ctx->eFrameType = IMG_INTRA_IDR;
956
957 drv_debug_msg(VIDEO_DEBUG_GENERAL,"%s: ctx->eFrameType = %d\n", __FUNCTION__, ctx->eFrameType);
958
959 return VA_STATUS_SUCCESS;
960 }
961
962 static IMG_UINT16 H264_ROUNDING_OFFSETS[18][4] = {
963 { 683, 683, 683, 683 }, /* 0 I-Slice - INTRA4 LUMA */
964 { 683, 683, 683, 683 }, /* 1 P-Slice - INTRA4 LUMA */
965 { 683, 683, 683, 683 }, /* 2 B-Slice - INTRA4 LUMA */
966
967 { 683, 683, 683, 683 }, /* 3 I-Slice - INTRA8 LUMA */
968 { 683, 683, 683, 683 }, /* 4 P-Slice - INTRA8 LUMA */
969 { 683, 683, 683, 683 }, /* 5 B-Slice - INTRA8 LUMA */
970 { 341, 341, 341, 341 }, /* 6 P-Slice - INTER8 LUMA */
971 { 341, 341, 341, 341 }, /* 7 B-Slice - INTER8 LUMA */
972
973 { 683, 683, 683, 000 }, /* 8 I-Slice - INTRA16 LUMA */
974 { 683, 683, 683, 000 }, /* 9 P-Slice - INTRA16 LUMA */
975 { 683, 683, 683, 000 }, /* 10 B-Slice - INTRA16 LUMA */
976 { 341, 341, 341, 341 }, /* 11 P-Slice - INTER16 LUMA */
977 { 341, 341, 341, 341 }, /* 12 B-Slice - INTER16 LUMA */
978
979 { 683, 683, 683, 000 }, /* 13 I-Slice - INTRA16 CHROMA */
980 { 683, 683, 683, 000 }, /* 14 P-Slice - INTRA16 CHROMA */
981 { 683, 683, 683, 000 }, /* 15 B-Slice - INTRA16 CHROMA */
982 { 341, 341, 341, 000 }, /* 16 P-Slice - INTER16 CHROMA */
983 { 341, 341, 341, 000 } /* 17 B-Slice - INTER16 CHROMA */
984 };
985
tng__create_gop_frame(IMG_UINT8 * pui8Level,IMG_BOOL bReference,IMG_UINT8 ui8Pos,IMG_UINT8 ui8Ref0Level,IMG_UINT8 ui8Ref1Level,IMG_FRAME_TYPE eFrameType)986 static IMG_UINT16 tng__create_gop_frame(
987 IMG_UINT8 * pui8Level, IMG_BOOL bReference,
988 IMG_UINT8 ui8Pos, IMG_UINT8 ui8Ref0Level,
989 IMG_UINT8 ui8Ref1Level, IMG_FRAME_TYPE eFrameType)
990 {
991 *pui8Level = ((ui8Ref0Level > ui8Ref1Level) ? ui8Ref0Level : ui8Ref1Level) + 1;
992
993 return F_ENCODE(bReference, GOP_REFERENCE) |
994 F_ENCODE(ui8Pos, GOP_POS) |
995 F_ENCODE(ui8Ref0Level, GOP_REF0) |
996 F_ENCODE(ui8Ref1Level, GOP_REF1) |
997 F_ENCODE(eFrameType, GOP_FRAMETYPE);
998 }
999
tng__minigop_generate_flat(void * buffer_p,IMG_UINT32 ui32BFrameCount,IMG_UINT32 ui32RefSpacing,IMG_UINT8 aui8PicOnLevel[])1000 static void tng__minigop_generate_flat(void* buffer_p, IMG_UINT32 ui32BFrameCount, IMG_UINT32 ui32RefSpacing, IMG_UINT8 aui8PicOnLevel[])
1001 {
1002 /* B B B B P */
1003 IMG_UINT8 ui8EncodeOrderPos;
1004 IMG_UINT8 ui8Level;
1005 IMG_UINT16 * psGopStructure = (IMG_UINT16 *)buffer_p;
1006
1007 psGopStructure[0] = tng__create_gop_frame(&ui8Level, IMG_TRUE, MAX_BFRAMES, ui32RefSpacing, 0, IMG_INTER_P);
1008 aui8PicOnLevel[ui8Level]++;
1009
1010 for (ui8EncodeOrderPos = 1; ui8EncodeOrderPos < MAX_GOP_SIZE; ui8EncodeOrderPos++) {
1011 psGopStructure[ui8EncodeOrderPos] = tng__create_gop_frame(&ui8Level, IMG_FALSE,
1012 ui8EncodeOrderPos - 1, ui32RefSpacing, ui32RefSpacing + 1, IMG_INTER_B);
1013 aui8PicOnLevel[ui8Level] = ui32BFrameCount;
1014 }
1015
1016 for( ui8EncodeOrderPos = 0; ui8EncodeOrderPos < MAX_GOP_SIZE; ui8EncodeOrderPos++) {
1017 drv_debug_msg(VIDEO_DEBUG_GENERAL,
1018 "%s: psGopStructure = 0x%06x\n", __FUNCTION__, psGopStructure[ui8EncodeOrderPos]);
1019 }
1020
1021 return ;
1022 }
1023
tng__gop_split(IMG_UINT16 ** pasGopStructure,IMG_INT8 i8Ref0,IMG_INT8 i8Ref1,IMG_UINT8 ui8Ref0Level,IMG_UINT8 ui8Ref1Level,IMG_UINT8 aui8PicOnLevel[])1024 static void tng__gop_split(IMG_UINT16 ** pasGopStructure, IMG_INT8 i8Ref0, IMG_INT8 i8Ref1,
1025 IMG_UINT8 ui8Ref0Level, IMG_UINT8 ui8Ref1Level, IMG_UINT8 aui8PicOnLevel[])
1026 {
1027 IMG_UINT8 ui8Distance = i8Ref1 - i8Ref0;
1028 IMG_UINT8 ui8Position = i8Ref0 + (ui8Distance >> 1);
1029 IMG_UINT8 ui8Level;
1030
1031 if (ui8Distance == 1)
1032 return;
1033
1034 /* mark middle as this level */
1035
1036 (*pasGopStructure)++;
1037 **pasGopStructure = tng__create_gop_frame(&ui8Level, ui8Distance >= 3, ui8Position, ui8Ref0Level, ui8Ref1Level, IMG_INTER_B);
1038 aui8PicOnLevel[ui8Level]++;
1039
1040 if (ui8Distance >= 4)
1041 tng__gop_split(pasGopStructure, i8Ref0, ui8Position, ui8Ref0Level, ui8Level, aui8PicOnLevel);
1042
1043 if (ui8Distance >= 3)
1044 tng__gop_split(pasGopStructure, ui8Position, i8Ref1, ui8Level, ui8Ref1Level, aui8PicOnLevel);
1045 }
1046
tng_minigop_generate_hierarchical(void * buffer_p,IMG_UINT32 ui32BFrameCount,IMG_UINT32 ui32RefSpacing,IMG_UINT8 aui8PicOnLevel[])1047 static void tng_minigop_generate_hierarchical(void* buffer_p, IMG_UINT32 ui32BFrameCount,
1048 IMG_UINT32 ui32RefSpacing, IMG_UINT8 aui8PicOnLevel[])
1049 {
1050 IMG_UINT8 ui8Level;
1051 IMG_UINT16 * psGopStructure = (IMG_UINT16 *)buffer_p;
1052
1053 psGopStructure[0] = tng__create_gop_frame(&ui8Level, IMG_TRUE, ui32BFrameCount, ui32RefSpacing, 0, IMG_INTER_P);
1054 aui8PicOnLevel[ui8Level]++;
1055
1056 tng__gop_split(&psGopStructure, -1, ui32BFrameCount, ui32RefSpacing, ui32RefSpacing + 1, aui8PicOnLevel);
1057 }
1058
tng__generate_scale_tables(IMG_MTX_VIDEO_CONTEXT * psMtxEncCtx)1059 static void tng__generate_scale_tables(IMG_MTX_VIDEO_CONTEXT* psMtxEncCtx)
1060 {
1061 psMtxEncCtx->ui32InterIntraScale[0] = 0x0004; // Force intra by scaling its cost by 0
1062 psMtxEncCtx->ui32InterIntraScale[1] = 0x0103; // favour intra by a factor 3
1063 psMtxEncCtx->ui32InterIntraScale[2] = 0x0102; // favour intra by a factor 2
1064 psMtxEncCtx->ui32InterIntraScale[3] = 0x0101; // no bias
1065 psMtxEncCtx->ui32InterIntraScale[4] = 0x0101; // no bias
1066 psMtxEncCtx->ui32InterIntraScale[5] = 0x0201; // favour inter by a factor 2
1067 psMtxEncCtx->ui32InterIntraScale[6] = 0x0301; // favour inter by a factor 3
1068 psMtxEncCtx->ui32InterIntraScale[7] = 0x0400; // Force inter by scaling it's cost by 0
1069
1070 psMtxEncCtx->ui32SkippedCodedScale[0] = 0x0004; // Force coded by scaling its cost by 0
1071 psMtxEncCtx->ui32SkippedCodedScale[1] = 0x0103; // favour coded by a factor 3
1072 psMtxEncCtx->ui32SkippedCodedScale[2] = 0x0102; // favour coded by a factor 2
1073 psMtxEncCtx->ui32SkippedCodedScale[3] = 0x0101; // no bias
1074 psMtxEncCtx->ui32SkippedCodedScale[4] = 0x0101; // no bias
1075 psMtxEncCtx->ui32SkippedCodedScale[5] = 0x0201; // favour skipped by a factor 2
1076 psMtxEncCtx->ui32SkippedCodedScale[6] = 0x0301; // favour skipped by a factor 3
1077 psMtxEncCtx->ui32SkippedCodedScale[7] = 0x0400; // Force skipped by scaling it's cost by 0
1078 return ;
1079 }
1080
1081 /*!
1082 ******************************************************************************
1083 @Function tng_update_driver_mv_scaling
1084 @details
1085 Setup the registers for scaling candidate motion vectors to take into account
1086 how far away (temporally) the reference pictures are
1087 ******************************************************************************/
1088
tng__abs(IMG_INT a)1089 static IMG_INT tng__abs(IMG_INT a)
1090 {
1091 if (a < 0)
1092 return -a;
1093 else
1094 return a;
1095 }
1096
tng__abs32(IMG_INT32 a)1097 static IMG_INT tng__abs32(IMG_INT32 a)
1098 {
1099 if (a < 0)
1100 return -a;
1101 else
1102 return a;
1103 }
1104
tng_update_driver_mv_scaling(IMG_UINT32 uFrameNum,IMG_UINT32 uRef0Num,IMG_UINT32 uRef1Num,IMG_UINT32 ui32PicFlags,IMG_BOOL bSkipDuplicateVectors,IMG_UINT32 * pui32MVCalc_Below,IMG_UINT32 * pui32MVCalc_Colocated,IMG_UINT32 * pui32MVCalc_Config)1105 void tng_update_driver_mv_scaling(
1106 IMG_UINT32 uFrameNum,
1107 IMG_UINT32 uRef0Num,
1108 IMG_UINT32 uRef1Num,
1109 IMG_UINT32 ui32PicFlags,
1110 IMG_BOOL bSkipDuplicateVectors,
1111 IMG_UINT32 * pui32MVCalc_Below,
1112 IMG_UINT32 * pui32MVCalc_Colocated,
1113 IMG_UINT32 * pui32MVCalc_Config)
1114 {
1115 IMG_UINT32 uMvCalcConfig = 0;
1116 IMG_UINT32 uMvCalcColocated = F_ENCODE(0x10, TOPAZHP_CR_TEMPORAL_BLEND);
1117 IMG_UINT32 uMvCalcBelow = 0;
1118
1119 //If b picture calculate scaling factor for colocated motion vectors
1120 if (ui32PicFlags & ISINTERB_FLAGS) {
1121 IMG_INT tb, td, tx;
1122 IMG_INT iDistScale;
1123
1124 //calculation taken from H264 spec
1125 tb = (uFrameNum * 2) - (uRef1Num * 2);
1126 td = (uRef0Num * 2) - (uRef1Num * 2);
1127 tx = (16384 + tng__abs(td / 2)) / td;
1128 iDistScale = (tb * tx + 32) >> 6;
1129 if (iDistScale > 1023) iDistScale = 1023;
1130 if (iDistScale < -1024) iDistScale = -1024;
1131 uMvCalcColocated |= F_ENCODE(iDistScale, TOPAZHP_CR_COL_DIST_SCALE_FACT);
1132
1133 //We assume the below temporal mvs are from the latest reference frame
1134 //rather then the most recently encoded B frame (as Bs aren't reference)
1135
1136 //Fwd temporal is same as colocated mv scale
1137 uMvCalcBelow |= F_ENCODE(iDistScale, TOPAZHP_CR_PIC0_DIST_SCALE_FACTOR);
1138
1139 //Bkwd temporal needs to be scaled by the recipricol amount in the other direction
1140 tb = (uFrameNum * 2) - (uRef0Num * 2);
1141 td = (uRef0Num * 2) - (uRef1Num * 2);
1142 tx = (16384 + tng__abs(td / 2)) / td;
1143 iDistScale = (tb * tx + 32) >> 6;
1144 if (iDistScale > 1023) iDistScale = 1023;
1145 if (iDistScale < -1024) iDistScale = -1024;
1146 uMvCalcBelow |= F_ENCODE(iDistScale, TOPAZHP_CR_PIC1_DIST_SCALE_FACTOR);
1147 } else {
1148 //Don't scale the temporal below mvs
1149 uMvCalcBelow |= F_ENCODE(1 << 8, TOPAZHP_CR_PIC0_DIST_SCALE_FACTOR);
1150
1151 if (uRef0Num != uRef1Num) {
1152 IMG_INT iRef0Dist, iRef1Dist;
1153 IMG_INT iScale;
1154
1155 //Distance to second reference picture may be different when
1156 //using multiple reference frames on P. Scale based on difference
1157 //in temporal distance to ref pic 1 compared to distance to ref pic 0
1158 iRef0Dist = (uFrameNum - uRef0Num);
1159 iRef1Dist = (uFrameNum - uRef1Num);
1160 iScale = (iRef1Dist << 8) / iRef0Dist;
1161
1162 if (iScale > 1023) iScale = 1023;
1163 if (iScale < -1024) iScale = -1024;
1164
1165 uMvCalcBelow |= F_ENCODE(iScale, TOPAZHP_CR_PIC1_DIST_SCALE_FACTOR);
1166 } else
1167 uMvCalcBelow |= F_ENCODE(1 << 8, TOPAZHP_CR_PIC1_DIST_SCALE_FACTOR);
1168 }
1169
1170 if (uFrameNum > 0) {
1171 IMG_INT ref0_distance, ref1_distance;
1172 IMG_INT jitter0, jitter1;
1173
1174 ref0_distance = tng__abs32((IMG_INT32)uFrameNum - (IMG_INT32)uRef0Num);
1175 ref1_distance = tng__abs32((IMG_INT32)uFrameNum - (IMG_INT32)uRef1Num);
1176
1177 if (!(ui32PicFlags & ISINTERB_FLAGS)) {
1178 jitter0 = ref0_distance * 1;
1179 jitter1 = jitter0 > 1 ? 1 : 2;
1180 } else {
1181 jitter0 = ref1_distance * 1;
1182 jitter1 = ref0_distance * 1;
1183 }
1184
1185 //Hardware can only cope with 1 - 4 jitter factors
1186 jitter0 = (jitter0 > 4) ? 4 : (jitter0 < 1) ? 1 : jitter0;
1187 jitter1 = (jitter1 > 4) ? 4 : (jitter1 < 1) ? 1 : jitter1;
1188
1189 //Hardware can only cope with 1 - 4 jitter factors
1190 assert(jitter0 > 0 && jitter0 <= 4 && jitter1 > 0 && jitter1 <= 4);
1191
1192 uMvCalcConfig |= F_ENCODE(jitter0 - 1, TOPAZHP_CR_MVCALC_IPE0_JITTER_FACTOR) |
1193 F_ENCODE(jitter1 - 1, TOPAZHP_CR_MVCALC_IPE1_JITTER_FACTOR);
1194 }
1195
1196 uMvCalcConfig |= F_ENCODE(1, TOPAZHP_CR_MVCALC_DUP_VEC_MARGIN);
1197 uMvCalcConfig |= F_ENCODE(7, TOPAZHP_CR_MVCALC_GRID_MB_X_STEP);
1198 uMvCalcConfig |= F_ENCODE(13, TOPAZHP_CR_MVCALC_GRID_MB_Y_STEP);
1199 uMvCalcConfig |= F_ENCODE(3, TOPAZHP_CR_MVCALC_GRID_SUB_STEP);
1200 uMvCalcConfig |= F_ENCODE(1, TOPAZHP_CR_MVCALC_GRID_DISABLE);
1201
1202 if (bSkipDuplicateVectors)
1203 uMvCalcConfig |= F_ENCODE(1, TOPAZHP_CR_MVCALC_NO_PSEUDO_DUPLICATES);
1204
1205 * pui32MVCalc_Below = uMvCalcBelow;
1206 * pui32MVCalc_Colocated = uMvCalcColocated;
1207 * pui32MVCalc_Config = uMvCalcConfig;
1208 }
1209
tng__prepare_mv_estimates(context_ENC_p ctx,IMG_UINT32 ui32StreamIndex)1210 static void tng__prepare_mv_estimates(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
1211 {
1212 context_ENC_mem* ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
1213 IMG_MTX_VIDEO_CONTEXT* psMtxEncCtx = NULL;
1214 IMG_UINT32 ui32Distance;
1215
1216 psb_buffer_map(&(ps_mem->bufs_mtx_context), &(ps_mem->bufs_mtx_context.virtual_addr));
1217 if (ps_mem->bufs_mtx_context.virtual_addr == NULL) {
1218 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping mtx context\n", __FUNCTION__);
1219 return ;
1220 }
1221
1222 psMtxEncCtx = (IMG_MTX_VIDEO_CONTEXT*)(ps_mem->bufs_mtx_context.virtual_addr);
1223
1224 /* IDR */
1225 psMtxEncCtx->sMVSettingsIdr.ui32MVCalc_Config = DEFAULT_MVCALC_CONFIG; // default based on TRM
1226 psMtxEncCtx->sMVSettingsIdr.ui32MVCalc_Colocated = 0x00100100;// default based on TRM
1227 psMtxEncCtx->sMVSettingsIdr.ui32MVCalc_Below = 0x01000100; // default based on TRM
1228
1229 tng_update_driver_mv_scaling(
1230 0, 0, 0, 0, IMG_FALSE, //psMtxEncCtx->bSkipDuplicateVectors, //By default false Newly Added
1231 &psMtxEncCtx->sMVSettingsIdr.ui32MVCalc_Below,
1232 &psMtxEncCtx->sMVSettingsIdr.ui32MVCalc_Colocated,
1233 &psMtxEncCtx->sMVSettingsIdr.ui32MVCalc_Config);
1234
1235 /* NonB (I or P) */
1236 for (ui32Distance = 1; ui32Distance <= MAX_BFRAMES + 1; ui32Distance++) {
1237 psMtxEncCtx->sMVSettingsNonB[ui32Distance - 1].ui32MVCalc_Config = DEFAULT_MVCALC_CONFIG; // default based on TRM
1238 psMtxEncCtx->sMVSettingsNonB[ui32Distance - 1].ui32MVCalc_Colocated = 0x00100100;// default based on TRM
1239 psMtxEncCtx->sMVSettingsNonB[ui32Distance - 1].ui32MVCalc_Below = 0x01000100; // default based on TRM
1240
1241
1242 tng_update_driver_mv_scaling(ui32Distance, 0, 0, 0, IMG_FALSE, //psMtxEncCtx->bSkipDuplicateVectors,
1243 &psMtxEncCtx->sMVSettingsNonB[ui32Distance - 1].ui32MVCalc_Below,
1244 &psMtxEncCtx->sMVSettingsNonB[ui32Distance - 1].ui32MVCalc_Colocated,
1245 &psMtxEncCtx->sMVSettingsNonB[ui32Distance - 1].ui32MVCalc_Config);
1246 }
1247
1248 {
1249 IMG_UINT32 ui32DistanceB;
1250 IMG_UINT32 ui32Position;
1251 context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
1252 IMG_MV_SETTINGS *pHostMVSettingsHierarchical = NULL;
1253 IMG_MV_SETTINGS *pMvElement = NULL;
1254 IMG_MV_SETTINGS *pHostMVSettingsBTable = NULL;
1255
1256 psb_buffer_map(&(ps_mem->bufs_mv_setting_btable), &(ps_mem->bufs_mv_setting_btable.virtual_addr));
1257 if (ps_mem->bufs_mv_setting_btable.virtual_addr == NULL) {
1258 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping mv setting btable\n", __FUNCTION__);
1259 return ;
1260 }
1261
1262 pHostMVSettingsBTable = (IMG_MV_SETTINGS *)(ps_mem->bufs_mv_setting_btable.virtual_addr);
1263
1264 for (ui32DistanceB = 0; ui32DistanceB < MAX_BFRAMES; ui32DistanceB++) {
1265 for (ui32Position = 1; ui32Position <= ui32DistanceB + 1; ui32Position++) {
1266 pMvElement = (IMG_MV_SETTINGS * ) ((IMG_UINT8 *) pHostMVSettingsBTable + MV_OFFSET_IN_TABLE(ui32DistanceB, ui32Position - 1));
1267 pMvElement->ui32MVCalc_Config= (DEFAULT_MVCALC_CONFIG|MASK_TOPAZHP_CR_MVCALC_GRID_DISABLE); // default based on TRM
1268 pMvElement->ui32MVCalc_Colocated=0x00100100;// default based on TRM
1269 pMvElement->ui32MVCalc_Below=0x01000100; // default based on TRM
1270
1271 tng_update_driver_mv_scaling(
1272 ui32Position, ui32DistanceB + 2, 0, ISINTERB_FLAGS, IMG_FALSE,
1273 &pMvElement->ui32MVCalc_Below,
1274 &pMvElement->ui32MVCalc_Colocated,
1275 &pMvElement->ui32MVCalc_Config);
1276 }
1277 }
1278
1279 if (ctx->b_is_mv_setting_hierar){
1280 pHostMVSettingsHierarchical = (IMG_MV_SETTINGS *)(ps_mem->bufs_mv_setting_hierar.virtual_addr);
1281
1282 for (ui32DistanceB = 0; ui32DistanceB < MAX_BFRAMES; ui32DistanceB++) {
1283 pMvElement = (IMG_MV_SETTINGS * ) ((IMG_UINT8 *)pHostMVSettingsBTable + MV_OFFSET_IN_TABLE(ui32DistanceB, ui32DistanceB >> 1));
1284 //memcpy(pHostMVSettingsHierarchical + ui32DistanceB, , sizeof(IMG_MV_SETTINGS));
1285 pHostMVSettingsHierarchical[ui32DistanceB].ui32MVCalc_Config = pMvElement->ui32MVCalc_Config;
1286 pHostMVSettingsHierarchical[ui32DistanceB].ui32MVCalc_Colocated = pMvElement->ui32MVCalc_Colocated;
1287 pHostMVSettingsHierarchical[ui32DistanceB].ui32MVCalc_Below = pMvElement->ui32MVCalc_Below;
1288 }
1289 }
1290 psb_buffer_unmap(&(ps_mem->bufs_mv_setting_btable));
1291 }
1292
1293 psb_buffer_unmap(&(ps_mem->bufs_mtx_context));
1294
1295 return ;
1296 }
1297
tng__adjust_picflags(context_ENC_p ctx,IMG_RC_PARAMS * psRCParams,IMG_BOOL bFirstPic,IMG_UINT32 * pui32Flags)1298 static void tng__adjust_picflags(
1299 context_ENC_p ctx,
1300 IMG_RC_PARAMS * psRCParams,
1301 IMG_BOOL bFirstPic,
1302 IMG_UINT32 * pui32Flags)
1303 {
1304 IMG_UINT32 ui32Flags;
1305 PIC_PARAMS * psPicParams = &ctx->sPicParams;
1306 ui32Flags = psPicParams->ui32Flags;
1307
1308 if (!psRCParams->bRCEnable || (!bFirstPic))
1309 ui32Flags = 0;
1310
1311 switch (ctx->eStandard) {
1312 case IMG_STANDARD_NONE:
1313 break;
1314 case IMG_STANDARD_H264:
1315 break;
1316 case IMG_STANDARD_H263:
1317 ui32Flags |= ISH263_FLAGS;
1318 break;
1319 case IMG_STANDARD_MPEG4:
1320 ui32Flags |= ISMPEG4_FLAGS;
1321 break;
1322 case IMG_STANDARD_MPEG2:
1323 ui32Flags |= ISMPEG2_FLAGS;
1324 break;
1325 default:
1326 break;
1327 }
1328 * pui32Flags = ui32Flags;
1329 }
1330
1331 #define gbLowLatency 0
1332
tng__setup_rcdata(context_ENC_p ctx)1333 static void tng__setup_rcdata(context_ENC_p ctx)
1334 {
1335 IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
1336 PIC_PARAMS *psPicParams = &(ctx->sPicParams);
1337
1338 IMG_INT32 i32FrameRate, i32TmpQp;
1339 double L1, L2, L3,L4, L5, L6, flBpp;
1340 IMG_INT32 i32BufferSizeInFrames;
1341
1342 if (ctx->bInsertHRDParams &&
1343 (ctx->eStandard == IMG_STANDARD_H264)) {
1344 psRCParams->ui32BufferSize = ctx->buffer_size;
1345 psRCParams->i32InitialLevel = ctx->buffer_size - ctx->initial_buffer_fullness;
1346 psRCParams->i32InitialDelay = ctx->initial_buffer_fullness;
1347 }
1348
1349 // If Bit Rate and Basic Units are not specified then set to default values.
1350 if (psRCParams->ui32BitsPerSecond == 0 && !ctx->bEnableMVC) {
1351 psRCParams->ui32BitsPerSecond = 640000; // kbps
1352 }
1353
1354 if (!psRCParams->ui32BUSize) {
1355 psRCParams->ui32BUSize = (ctx->ui16PictureHeight>>4) * (ctx->ui16Width>>4); // BU = 1 Frame
1356 }
1357
1358 if (!psRCParams->ui32FrameRate) {
1359 psRCParams->ui32FrameRate = 30; // fps
1360 }
1361
1362 // Calculate Bits Per Pixel
1363 if (ctx->ui16Width <= 176 ) {
1364 i32FrameRate = 30;
1365 } else {
1366 i32FrameRate = psRCParams->ui32FrameRate;
1367 }
1368
1369 flBpp = 1.0 * psRCParams->ui32BitsPerSecond / (i32FrameRate * ctx->ui16Width * ctx->ui16FrameHeight);
1370
1371 psPicParams->sInParams.ui8SeInitQP = psRCParams->ui32InitialQp;
1372 psPicParams->sInParams.ui8MBPerRow = (ctx->ui16Width>>4);
1373 psPicParams->sInParams.ui16MBPerBU = psRCParams->ui32BUSize;
1374 psPicParams->sInParams.ui16MBPerFrm = (ctx->ui16Width>>4) * (ctx->ui16PictureHeight>>4);
1375 psPicParams->sInParams.ui16BUPerFrm = (psPicParams->sInParams.ui16MBPerFrm) / psRCParams->ui32BUSize;
1376
1377 psPicParams->sInParams.ui16IntraPeriod = psRCParams->ui32IntraFreq;
1378 psPicParams->sInParams.ui16BFrames = psRCParams->ui16BFrames;
1379 psPicParams->sInParams.i32BitRate = psRCParams->ui32BitsPerSecond;
1380
1381 psPicParams->sInParams.bFrmSkipDisable = psRCParams->bDisableFrameSkipping;
1382 psPicParams->sInParams.i32BitsPerFrm = (psRCParams->ui32BitsPerSecond + psRCParams->ui32FrameRate/2) / psRCParams->ui32FrameRate;
1383 psPicParams->sInParams.i32BitsPerBU = psPicParams->sInParams.i32BitsPerFrm / (4 * psPicParams->sInParams.ui16BUPerFrm);
1384
1385 // Codec-dependant fields
1386 if (ctx->eStandard == IMG_STANDARD_H264) {
1387 psPicParams->sInParams.mode.h264.i32TransferRate = (psRCParams->ui32TransferBitsPerSecond + psRCParams->ui32FrameRate/2) / psRCParams->ui32FrameRate;
1388 psPicParams->sInParams.mode.h264.bHierarchicalMode = psRCParams->b16Hierarchical;
1389 } else {
1390 psPicParams->sInParams.mode.other.i32BitsPerGOP = (psRCParams->ui32BitsPerSecond / psRCParams->ui32FrameRate) * psRCParams->ui32IntraFreq;
1391 psPicParams->sInParams.mode.other.ui16AvQPVal = psRCParams->ui32InitialQp;
1392 psPicParams->sInParams.mode.other.ui16MyInitQP = psRCParams->ui32InitialQp;
1393 }
1394
1395
1396 if (psPicParams->sInParams.i32BitsPerFrm) {
1397 i32BufferSizeInFrames = (psRCParams->ui32BufferSize + (psPicParams->sInParams.i32BitsPerFrm/2))/psPicParams->sInParams.i32BitsPerFrm;
1398 } else {
1399 IMG_ASSERT(ctx->bEnableMvc && "Can happen only in MVC mode");
1400 /* Asigning more or less `normal` value. To be overriden by MVC RC module */
1401 i32BufferSizeInFrames = 30;
1402 }
1403
1404 // select thresholds and initial Qps etc that are codec dependent
1405 switch (ctx->eStandard) {
1406 case IMG_STANDARD_H264:
1407 L1 = 0.1; L2 = 0.15; L3 = 0.2;
1408 psPicParams->sInParams.ui8MaxQPVal = 51;
1409 ctx->ui32KickSize = psPicParams->sInParams.ui16MBPerBU;
1410
1411 // Setup MAX and MIN Quant Values
1412 if (psRCParams->iMinQP == 0) {
1413 if (flBpp >= 0.50)
1414 i32TmpQp = 4;
1415 else if (flBpp > 0.133)
1416 i32TmpQp = (IMG_INT32)(22 - (40*flBpp));
1417 else
1418 i32TmpQp = (IMG_INT32)(30 - (100 * flBpp));
1419
1420 /* Adjust minQp up for small buffer size and down for large buffer size */
1421 if (i32BufferSizeInFrames < 5) {
1422 i32TmpQp += 2;
1423 }
1424
1425 if (i32BufferSizeInFrames > 40) {
1426 if(i32TmpQp>=1)
1427 i32TmpQp -= 1;
1428 }
1429 /* for HD content allow a lower minQp as bitrate is more easily controlled in this case */
1430 if (psPicParams->sInParams.ui16MBPerFrm > 2000) {
1431 i32TmpQp -= 6;
1432 }
1433 } else
1434 i32TmpQp = psRCParams->iMinQP;
1435
1436 if (i32TmpQp < 2) {
1437 psPicParams->sInParams.ui8MinQPVal = 2;
1438 } else {
1439 psPicParams->sInParams.ui8MinQPVal = i32TmpQp;
1440 }
1441
1442 // Calculate Initial QP if it has not been specified
1443 i32TmpQp = psPicParams->sInParams.ui8SeInitQP;
1444 if (psPicParams->sInParams.ui8SeInitQP==0) {
1445 L1 = 0.050568;
1446 L2 = 0.202272;
1447 L3 = 0.40454321;
1448 L4 = 0.80908642;
1449 L5 = 1.011358025;
1450
1451 if (flBpp < L1)
1452 i32TmpQp = (IMG_INT32)(45 - 78.10*flBpp);
1453 else if (flBpp>=L1 && flBpp<L2)
1454 i32TmpQp = (IMG_INT32)(44 - 72.51*flBpp);
1455 else if (flBpp>=L2 && flBpp<L3)
1456 i32TmpQp = (IMG_INT32)(34 - 24.72*flBpp);
1457 else if (flBpp>=L3 && flBpp<L4)
1458 i32TmpQp = (IMG_INT32)(32 - 19.78*flBpp);
1459 else if (flBpp>=L4 && flBpp<L5)
1460 i32TmpQp = (IMG_INT32)(25 - 9.89*flBpp);
1461 else if (flBpp>=L5)
1462 i32TmpQp = (IMG_INT32)(18 - 4.95*flBpp);
1463
1464 /* Adjust ui8SeInitQP up for small buffer size or small fps */
1465 /* Adjust ui8SeInitQP up for small gop size */
1466 if ((i32BufferSizeInFrames < 20) || (psRCParams->ui32IntraFreq < 20)) {
1467 i32TmpQp += 2;
1468 }
1469
1470 /* for very small buffers increase initial Qp even more */
1471 if(i32BufferSizeInFrames < 5)
1472 {
1473 i32TmpQp += 8;
1474 }
1475
1476 /* start on a lower initial Qp for HD content as the coding is more efficient */
1477 if (psPicParams->sInParams.ui16MBPerFrm > 2000) {
1478 i32TmpQp -= 2;
1479 }
1480
1481 if(psPicParams->sInParams.ui16IntraPeriod ==1)
1482 {
1483 /* for very small GOPS start with a much higher initial Qp */
1484 i32TmpQp += 12;
1485 } else if (psPicParams->sInParams.ui16IntraPeriod<5) {
1486 /* for very small GOPS start with a much higher initial Qp */
1487 i32TmpQp += 6;
1488 }
1489 }
1490 if (i32TmpQp>49) {
1491 i32TmpQp = 49;
1492 }
1493 if (i32TmpQp < psPicParams->sInParams.ui8MinQPVal) {
1494 i32TmpQp = psPicParams->sInParams.ui8MinQPVal;
1495 }
1496 psPicParams->sInParams.ui8SeInitQP = i32TmpQp;
1497
1498 if(flBpp <= 0.3)
1499 psPicParams->ui32Flags |= ISRC_I16BIAS;
1500
1501 break;
1502
1503 case IMG_STANDARD_MPEG4:
1504 case IMG_STANDARD_MPEG2:
1505 case IMG_STANDARD_H263:
1506 psPicParams->sInParams.ui8MaxQPVal = 31;
1507 if (ctx->ui16Width == 176) {
1508 L1 = 0.042; L2 = 0.084; L3 = 0.126; L4 = 0.168; L5 = 0.336; L6=0.505;
1509 } else if (ctx->ui16Width == 352) {
1510 L1 = 0.064; L2 = 0.084; L3 = 0.106; L4 = 0.126; L5 = 0.168; L6=0.210;
1511 } else {
1512 L1 = 0.050; L2 = 0.0760; L3 = 0.096; L4 = 0.145; L5 = 0.193; L6=0.289;
1513 }
1514
1515 if (psPicParams->sInParams.ui8SeInitQP==0) {
1516 if (flBpp < L1)
1517 psPicParams->sInParams.ui8SeInitQP = 31;
1518 else if (flBpp>=L1 && flBpp<L2)
1519 psPicParams->sInParams.ui8SeInitQP = 26;
1520 else if (flBpp>=L2 && flBpp<L3)
1521 psPicParams->sInParams.ui8SeInitQP = 22;
1522 else if (flBpp>=L3 && flBpp<L4)
1523 psPicParams->sInParams.ui8SeInitQP = 18;
1524 else if (flBpp>=L4 && flBpp<L5)
1525 psPicParams->sInParams.ui8SeInitQP = 14;
1526 else if (flBpp>=L5 && flBpp<L6)
1527 psPicParams->sInParams.ui8SeInitQP = 10;
1528 else
1529 psPicParams->sInParams.ui8SeInitQP = 8;
1530
1531 /* Adjust ui8SeInitQP up for small buffer size or small fps */
1532 /* Adjust ui8SeInitQP up for small gop size */
1533 if ((i32BufferSizeInFrames < 20) || (psRCParams->ui32IntraFreq < 20)) {
1534 psPicParams->sInParams.ui8SeInitQP += 2;
1535 }
1536
1537 if (psPicParams->sInParams.ui8SeInitQP > psPicParams->sInParams.ui8MaxQPVal) {
1538 psPicParams->sInParams.ui8SeInitQP = psPicParams->sInParams.ui8MaxQPVal;
1539 }
1540 psPicParams->sInParams.mode.other.ui16AvQPVal = psPicParams->sInParams.ui8SeInitQP;
1541 }
1542 psPicParams->sInParams.ui8MinQPVal = 2;
1543
1544 /* Adjust minQp up for small buffer size and down for large buffer size */
1545 if (i32BufferSizeInFrames < 20) {
1546 psPicParams->sInParams.ui8MinQPVal += 1;
1547 }
1548 break;
1549
1550 default:
1551 /* the NO RC cases will fall here */
1552 break;
1553 }
1554
1555 if (ctx->sRCParams.eRCMode == IMG_RCMODE_VBR) {
1556 psPicParams->sInParams.ui16MBPerBU = psPicParams->sInParams.ui16MBPerFrm;
1557 psPicParams->sInParams.ui16BUPerFrm = 1;
1558
1559 // Initialize the parameters of fluid flow traffic model.
1560 psPicParams->sInParams.i32BufferSize = psRCParams->ui32BufferSize;
1561
1562
1563 // These scale factor are used only for rate control to avoid overflow
1564 // in fixed-point calculation these scale factors are decided by bit rate
1565 if (psRCParams->ui32BitsPerSecond < 640000) {
1566 psPicParams->sInParams.ui8ScaleFactor = 2; // related to complexity
1567 }
1568 else if (psRCParams->ui32BitsPerSecond < 2000000) {
1569 // 2 Mbits
1570 psPicParams->sInParams.ui8ScaleFactor = 4;
1571 }
1572 else if(psRCParams->ui32BitsPerSecond < 8000000) {
1573 // 8 Mbits
1574 psPicParams->sInParams.ui8ScaleFactor = 6;
1575 } else
1576 psPicParams->sInParams.ui8ScaleFactor = 8;
1577 } else {
1578 // Set up Input Parameters that are mode dependent
1579 switch (ctx->eStandard) {
1580 case IMG_STANDARD_H264:
1581 // ------------------- H264 CBR RC ------------------- //
1582 // Initialize the parameters of fluid flow traffic model.
1583 psPicParams->sInParams.i32BufferSize = psRCParams->ui32BufferSize;
1584
1585 // HRD consideration - These values are used by H.264 reference code.
1586 if (psRCParams->ui32BitsPerSecond < 1000000) {
1587 // 1 Mbits/s
1588 psPicParams->sInParams.ui8ScaleFactor = 0;
1589 } else if (psRCParams->ui32BitsPerSecond < 2000000) {
1590 // 2 Mbits/s
1591 psPicParams->sInParams.ui8ScaleFactor = 1;
1592 } else if (psRCParams->ui32BitsPerSecond < 4000000) {
1593 // 4 Mbits/s
1594 psPicParams->sInParams.ui8ScaleFactor = 2;
1595 } else if (psRCParams->ui32BitsPerSecond < 8000000) {
1596 // 8 Mbits/s
1597 psPicParams->sInParams.ui8ScaleFactor = 3;
1598 } else {
1599 psPicParams->sInParams.ui8ScaleFactor = 4;
1600 }
1601
1602 if (ctx->sRCParams.eRCMode == IMG_RCMODE_VCM) {
1603 psPicParams->sInParams.i32BufferSize = i32BufferSizeInFrames;
1604 }
1605 break;
1606 case IMG_STANDARD_MPEG4:
1607 case IMG_STANDARD_MPEG2:
1608 case IMG_STANDARD_H263:
1609 flBpp = 256 * (psRCParams->ui32BitsPerSecond/ctx->ui16Width);
1610 flBpp /= (ctx->ui16FrameHeight * psRCParams->ui32FrameRate);
1611
1612 if ((psPicParams->sInParams.ui16MBPerFrm > 1024 && flBpp < 16) || (psPicParams->sInParams.ui16MBPerFrm <= 1024 && flBpp < 24))
1613 psPicParams->sInParams.mode.other.ui8HalfFrameRate = 1;
1614 else
1615 psPicParams->sInParams.mode.other.ui8HalfFrameRate = 0;
1616
1617 if (psPicParams->sInParams.mode.other.ui8HalfFrameRate >= 1) {
1618 psPicParams->sInParams.ui8SeInitQP = 31;
1619 psPicParams->sInParams.mode.other.ui16AvQPVal = 31;
1620 psPicParams->sInParams.mode.other.ui16MyInitQP = 31;
1621 }
1622
1623 psPicParams->sInParams.i32BufferSize = psRCParams->ui32BufferSize;
1624 break;
1625 default:
1626 break;
1627 }
1628 }
1629
1630 if (psRCParams->bScDetectDisable)
1631 psPicParams->ui32Flags |= ISSCENE_DISABLED;
1632
1633 psPicParams->sInParams.i32InitialDelay = psRCParams->i32InitialDelay;
1634 psPicParams->sInParams.i32InitialLevel = psRCParams->i32InitialLevel;
1635 psRCParams->ui32InitialQp = psPicParams->sInParams.ui8SeInitQP;
1636
1637 /* The rate control uses this value to adjust the reaction rate to larger than expected frames */
1638 if (ctx->eStandard == IMG_STANDARD_H264) {
1639 if (psPicParams->sInParams.i32BitsPerFrm) {
1640 const IMG_INT32 bitsPerGop = (psRCParams->ui32BitsPerSecond / psRCParams->ui32FrameRate) * psRCParams->ui32IntraFreq;
1641 psPicParams->sInParams.mode.h264.ui32RCScaleFactor = (bitsPerGop * 256) /
1642 (psPicParams->sInParams.i32BufferSize - psPicParams->sInParams.i32InitialLevel);
1643 } else {
1644 psPicParams->sInParams.mode.h264.ui32RCScaleFactor = 0;
1645 }
1646 } else {
1647 psPicParams->sInParams.mode.other.ui16MyInitQP = psPicParams->sInParams.ui8SeInitQP;
1648 }
1649
1650 return ;
1651 }
1652
tng__save_slice_params_template(context_ENC_p ctx,IMG_UINT32 ui32SliceBufIdx,IMG_UINT32 ui32SliceType,IMG_UINT32 ui32IPEControl,IMG_UINT32 ui32Flags,IMG_UINT32 ui32SliceConfig,IMG_UINT32 ui32SeqConfig,IMG_UINT32 ui32StreamIndex)1653 static void tng__save_slice_params_template(
1654 context_ENC_p ctx,
1655 IMG_UINT32 ui32SliceBufIdx,
1656 IMG_UINT32 ui32SliceType,
1657 IMG_UINT32 ui32IPEControl,
1658 IMG_UINT32 ui32Flags,
1659 IMG_UINT32 ui32SliceConfig,
1660 IMG_UINT32 ui32SeqConfig,
1661 IMG_UINT32 ui32StreamIndex
1662 )
1663 {
1664 IMG_FRAME_TEMPLATE_TYPE eSliceType = (IMG_FRAME_TEMPLATE_TYPE)ui32SliceType;
1665 context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
1666 SLICE_PARAMS *slice_temp_p = NULL;
1667
1668 psb_buffer_map(&(ps_mem->bufs_slice_template), &(ps_mem->bufs_slice_template.virtual_addr));
1669 if (ps_mem->bufs_slice_template.virtual_addr == NULL) {
1670 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping slice template\n", __FUNCTION__);
1671 return ;
1672 }
1673
1674 slice_temp_p = (SLICE_PARAMS*)(ps_mem->bufs_slice_template.virtual_addr + (ctx->ctx_mem_size.slice_template * ui32SliceBufIdx));
1675
1676 slice_temp_p->eTemplateType = eSliceType;
1677 slice_temp_p->ui32Flags = ui32Flags;
1678 slice_temp_p->ui32IPEControl = ui32IPEControl;
1679 slice_temp_p->ui32SliceConfig = ui32SliceConfig;
1680 slice_temp_p->ui32SeqConfig = ui32SeqConfig;
1681
1682 psb_buffer_unmap(&(ps_mem->bufs_slice_template));
1683
1684 return ;
1685 }
1686
1687
1688 /*****************************************************************************
1689 * Function Name : PrepareEncodeSliceParams
1690 *
1691 ****************************************************************************/
tng__prepare_encode_sliceparams(context_ENC_p ctx,IMG_UINT32 ui32SliceBufIdx,IMG_UINT32 ui32SliceType,IMG_UINT16 __maybe_unused ui16CurrentRow,IMG_UINT16 ui16SliceHeight,IMG_UINT8 uiDeblockIDC,IMG_BOOL bFieldMode,IMG_INT iFineYSearchSize,IMG_UINT32 ui32StreamIndex)1692 static IMG_UINT32 tng__prepare_encode_sliceparams(
1693 context_ENC_p ctx,
1694 IMG_UINT32 ui32SliceBufIdx,
1695 IMG_UINT32 ui32SliceType,
1696 IMG_UINT16 __maybe_unused ui16CurrentRow,
1697 IMG_UINT16 ui16SliceHeight,
1698 IMG_UINT8 uiDeblockIDC,
1699 IMG_BOOL bFieldMode,
1700 IMG_INT iFineYSearchSize,
1701 IMG_UINT32 ui32StreamIndex
1702 )
1703 {
1704 IMG_UINT32 ui32FrameStoreFormat;
1705 IMG_UINT8 ui8SwapChromas;
1706 IMG_UINT32 ui32MBsPerKick, ui32KicksPerSlice;
1707 IMG_UINT32 ui32IPEControl;
1708 IMG_UINT32 ui32Flags = 0;
1709 IMG_UINT32 ui32SliceConfig = 0;
1710 IMG_UINT32 ui32SeqConfig = 0;
1711 IMG_BOOL bIsIntra = IMG_FALSE;
1712 IMG_BOOL bIsBPicture = IMG_FALSE;
1713 IMG_BOOL bIsIDR = IMG_FALSE;
1714 IMG_IPE_MINBLOCKSIZE blkSz;
1715 IMG_FRAME_TEMPLATE_TYPE eSliceType = (IMG_FRAME_TEMPLATE_TYPE)ui32SliceType;
1716
1717 if (!ctx) {
1718 return VA_STATUS_ERROR_INVALID_CONTEXT;
1719 }
1720
1721 /* We want multiple ones of these so we can submit multiple slices without having to wait for the next*/
1722 ui32IPEControl = ctx->ui32IPEControl;
1723 bIsIntra = ((eSliceType == IMG_FRAME_IDR) || (eSliceType == IMG_FRAME_INTRA));
1724 bIsBPicture = (eSliceType == IMG_FRAME_INTER_B);
1725 bIsIDR = ((eSliceType == IMG_FRAME_IDR) || (eSliceType == IMG_FRAME_INTER_P_IDR));
1726
1727 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG bIsIntra = %x\n", __FUNCTION__, bIsIntra);
1728 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG bIsBFrame = %x\n", __FUNCTION__, bIsBPicture);
1729 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG bIsIDR = %x\n", __FUNCTION__, bIsIDR);
1730 /* extract block size */
1731 blkSz = F_EXTRACT(ui32IPEControl, TOPAZHP_CR_IPE_BLOCKSIZE);
1732 /* mask-out the block size bits from ui32IPEControl */
1733 ui32IPEControl &= ~(F_MASK(TOPAZHP_CR_IPE_BLOCKSIZE));
1734 switch (ctx->eStandard) {
1735 case IMG_STANDARD_NONE:
1736 case IMG_STANDARD_JPEG:
1737 break;
1738
1739 case IMG_STANDARD_H264:
1740 if (blkSz > 2) blkSz = 2;
1741 if (bIsBPicture) {
1742 if (blkSz > 1) blkSz = 1;
1743 }
1744 #ifdef BRN_30322
1745 else if (bIsIntra) {
1746 if (blkSz == 0) blkSz = 1; // Workaround for BRN 30322
1747 }
1748 #endif
1749
1750 #ifdef BRN_30550
1751 if (ctx->bCabacEnabled)
1752 if (blkSz == 0) blkSz = 1;
1753 #endif
1754 if (ctx->uMBspS >= _1080P_30FPS) {
1755 ui32IPEControl |= F_ENCODE(iFineYSearchSize, TOPAZHP_CR_IPE_LRITC_BOUNDARY) |
1756 F_ENCODE(iFineYSearchSize, TOPAZHP_CR_IPE_Y_FINE_SEARCH);
1757 } else {
1758 ui32IPEControl |= F_ENCODE(iFineYSearchSize + 1, TOPAZHP_CR_IPE_LRITC_BOUNDARY) |
1759 F_ENCODE(iFineYSearchSize, TOPAZHP_CR_IPE_Y_FINE_SEARCH);
1760
1761 }
1762 if (ctx->bLimitNumVectors)
1763 ui32IPEControl |= F_ENCODE(1, TOPAZHP_CR_IPE_MV_NUMBER_RESTRICTION);
1764 break;
1765
1766 case IMG_STANDARD_H263:
1767 blkSz = 0;
1768 ui32IPEControl = F_ENCODE(iFineYSearchSize + 1, TOPAZHP_CR_IPE_LRITC_BOUNDARY) |
1769 F_ENCODE(iFineYSearchSize, TOPAZHP_CR_IPE_Y_FINE_SEARCH) |
1770 F_ENCODE(0, TOPAZHP_CR_IPE_4X4_SEARCH);
1771 //We only support a maxium vector of 15.5 pixels in H263
1772 break;
1773
1774 case IMG_STANDARD_MPEG4:
1775 if (blkSz > BLK_SZ_8x8) blkSz = BLK_SZ_8x8;
1776 ui32IPEControl |= F_ENCODE(iFineYSearchSize + 1, TOPAZHP_CR_IPE_LRITC_BOUNDARY) |
1777 F_ENCODE(iFineYSearchSize, TOPAZHP_CR_IPE_Y_FINE_SEARCH) |
1778 F_ENCODE(0, TOPAZHP_CR_IPE_4X4_SEARCH);
1779 // FIXME Should be 1, set to zero for hardware testing.
1780 break;
1781 case IMG_STANDARD_MPEG2:
1782 if (blkSz != BLK_SZ_16x16) blkSz = BLK_SZ_16x16;
1783 ui32IPEControl |= F_ENCODE(iFineYSearchSize + 1, TOPAZHP_CR_IPE_LRITC_BOUNDARY) |
1784 F_ENCODE(iFineYSearchSize, TOPAZHP_CR_IPE_Y_FINE_SEARCH) |
1785 F_ENCODE(0, TOPAZHP_CR_IPE_4X4_SEARCH);
1786 // FIXME Should be 1, set to zero for hardware testing.
1787 break;
1788 }
1789
1790 {
1791 IMG_BOOL bRestrict4x4SearchSize;
1792 IMG_UINT32 uLritcBoundary;
1793
1794 if (ctx->uMBspS >= _1080P_30FPS)
1795 bRestrict4x4SearchSize = 1;
1796 else
1797 bRestrict4x4SearchSize = 0;
1798
1799 ui32IPEControl |= F_ENCODE(blkSz, TOPAZHP_CR_IPE_BLOCKSIZE);
1800 uLritcBoundary = (blkSz != BLK_SZ_16x16) ? (iFineYSearchSize + (bRestrict4x4SearchSize ? 0 : 1)) : 1;
1801 if (uLritcBoundary > 3) {
1802 return VA_STATUS_ERROR_UNKNOWN;
1803 }
1804
1805 /* Minium sub block size to calculate motion vectors for. 0=16x16, 1=8x8, 2=4x4 */
1806 ui32IPEControl = F_INSERT(ui32IPEControl, blkSz, TOPAZHP_CR_IPE_BLOCKSIZE);
1807 ui32IPEControl = F_INSERT(ui32IPEControl, iFineYSearchSize, TOPAZHP_CR_IPE_Y_FINE_SEARCH);
1808 ui32IPEControl = F_INSERT(ui32IPEControl, ctx->bLimitNumVectors, TOPAZHP_CR_IPE_MV_NUMBER_RESTRICTION);
1809
1810 ui32IPEControl = F_INSERT(ui32IPEControl, uLritcBoundary, TOPAZHP_CR_IPE_LRITC_BOUNDARY); // 8x8 search
1811 ui32IPEControl = F_INSERT(ui32IPEControl, bRestrict4x4SearchSize ? 0 : 1, TOPAZHP_CR_IPE_4X4_SEARCH);
1812
1813 }
1814 ui32IPEControl = F_INSERT(ui32IPEControl, ctx->bHighLatency, TOPAZHP_CR_IPE_HIGH_LATENCY);
1815 // psSliceParams->ui32IPEControl = ui32IPEControl;
1816
1817 if (!bIsIntra) {
1818 if (bIsBPicture)
1819 ui32Flags |= ISINTERB_FLAGS;
1820 else
1821 ui32Flags |= ISINTERP_FLAGS;
1822 }
1823 switch (ctx->eStandard) {
1824 case IMG_STANDARD_NONE:
1825 break;
1826 case IMG_STANDARD_H263:
1827 ui32Flags |= ISH263_FLAGS;
1828 break;
1829 case IMG_STANDARD_MPEG4:
1830 ui32Flags |= ISMPEG4_FLAGS;
1831 break;
1832 case IMG_STANDARD_MPEG2:
1833 ui32Flags |= ISMPEG2_FLAGS;
1834 break;
1835 default:
1836 break;
1837 }
1838
1839 if (ctx->bMultiReferenceP && !(bIsIntra || bIsBPicture))
1840 ui32Flags |= ISMULTIREF_FLAGS;
1841 if (ctx->bSpatialDirect && bIsBPicture)
1842 ui32Flags |= SPATIALDIRECT_FLAGS;
1843
1844 if (bIsIntra) {
1845 ui32SliceConfig = F_ENCODE(TOPAZHP_CR_SLICE_TYPE_I_SLICE, TOPAZHP_CR_SLICE_TYPE);
1846 } else {
1847 if (bIsBPicture) {
1848 ui32SliceConfig = F_ENCODE(TOPAZHP_CR_SLICE_TYPE_B_SLICE, TOPAZHP_CR_SLICE_TYPE);
1849 } else {
1850 // p frame
1851 ui32SliceConfig = F_ENCODE(TOPAZHP_CR_SLICE_TYPE_P_SLICE, TOPAZHP_CR_SLICE_TYPE);
1852 }
1853 }
1854
1855 ui32MBsPerKick = ctx->ui32KickSize;
1856 // we need to figure out the number of kicks and mb's per kick to use.
1857 // on H.264 we will use a MB's per kick of basic unit
1858 // on other rc varients we will use mb's per kick of width
1859 ui32KicksPerSlice = ((ui16SliceHeight / 16) * (ctx->ui16Width / 16)) / ui32MBsPerKick;
1860 assert((ui32KicksPerSlice * ui32MBsPerKick) == ((ui16SliceHeight / 16)*(ctx->ui16Width / 16)));
1861
1862 // need some sensible ones don't look to be implemented yet...
1863 // change per stream
1864
1865 if ((ctx->eFormat == IMG_CODEC_UY0VY1_8888) || (ctx->eFormat == IMG_CODEC_VY0UY1_8888))
1866 ui32FrameStoreFormat = 3;
1867 else if ((ctx->eFormat == IMG_CODEC_Y0UY1V_8888) || (ctx->eFormat == IMG_CODEC_Y0VY1U_8888))
1868 ui32FrameStoreFormat = 2;
1869 else if ((ctx->eFormat == IMG_CODEC_PL12) || (ctx->eFormat == IMG_CODEC_422_PL12))
1870 ui32FrameStoreFormat = 1;
1871 else
1872 ui32FrameStoreFormat = 0;
1873
1874 if ((ctx->eFormat == IMG_CODEC_VY0UY1_8888) || (ctx->eFormat == IMG_CODEC_Y0VY1U_8888))
1875 ui8SwapChromas = 1;
1876 else
1877 ui8SwapChromas = 0;
1878
1879 switch (ctx->eStandard) {
1880 case IMG_STANDARD_NONE:
1881 case IMG_STANDARD_JPEG:
1882 break;
1883 case IMG_STANDARD_H264:
1884 /* H264 */
1885
1886 ui32SeqConfig = F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC0_BELOW_IN_VALID)
1887 | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC1_BELOW_IN_VALID)
1888 | F_ENCODE(0, TOPAZHP_CR_ABOVE_OUT_OF_SLICE_VALID)
1889 | F_ENCODE(1, TOPAZHP_CR_WRITE_TEMPORAL_PIC0_BELOW_VALID)
1890 | F_ENCODE(0, TOPAZHP_CR_REF_PIC0_VALID)
1891 | F_ENCODE(0, TOPAZHP_CR_REF_PIC1_VALID)
1892 | F_ENCODE(!bIsBPicture, TOPAZHP_CR_REF_PIC1_EQUAL_PIC0)
1893 | F_ENCODE(bFieldMode ? 1 : 0 , TOPAZHP_CR_FIELD_MODE)
1894 | F_ENCODE(ui8SwapChromas, TOPAZHP_CR_FRAME_STORE_CHROMA_SWAP)
1895 | F_ENCODE(ui32FrameStoreFormat, TOPAZHP_CR_FRAME_STORE_FORMAT)
1896 | F_ENCODE(TOPAZHP_CR_ENCODER_STANDARD_H264, TOPAZHP_CR_ENCODER_STANDARD)
1897 | F_ENCODE(uiDeblockIDC == 1 ? 0 : 1, TOPAZHP_CR_DEBLOCK_ENABLE);
1898
1899 if (ctx->sRCParams.ui16BFrames) {
1900 ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_WRITE_TEMPORAL_COL_VALID);
1901 if ((ui32Flags & ISINTERB_FLAGS) == ISINTERB_FLAGS)
1902 ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_TEMPORAL_COL_IN_VALID);
1903 }
1904
1905 if (!bIsBPicture) {
1906 ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_WRITE_TEMPORAL_COL_VALID);
1907 }
1908
1909 break;
1910 case IMG_STANDARD_MPEG4:
1911 /* MPEG4 */
1912 ui32SeqConfig = F_ENCODE(1, TOPAZHP_CR_WRITE_RECON_PIC)
1913 | F_ENCODE(0, TOPAZHP_CR_DEBLOCK_ENABLE)
1914 | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC0_BELOW_IN_VALID)
1915 | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC1_BELOW_IN_VALID)
1916 | F_ENCODE(0, TOPAZHP_CR_ABOVE_OUT_OF_SLICE_VALID)
1917 | F_ENCODE(((ui32Flags & ISINTERP_FLAGS) == ISINTERP_FLAGS), TOPAZHP_CR_WRITE_TEMPORAL_PIC0_BELOW_VALID)
1918 | F_ENCODE(0, TOPAZHP_CR_REF_PIC0_VALID)
1919 | F_ENCODE(0, TOPAZHP_CR_REF_PIC1_VALID)
1920 | F_ENCODE(1, TOPAZHP_CR_REF_PIC1_EQUAL_PIC0)
1921 | F_ENCODE(0, TOPAZHP_CR_FIELD_MODE)
1922 | F_ENCODE(ui8SwapChromas, TOPAZHP_CR_FRAME_STORE_CHROMA_SWAP)
1923 | F_ENCODE(ui32FrameStoreFormat, TOPAZHP_CR_FRAME_STORE_FORMAT)
1924 | F_ENCODE(TOPAZHP_CR_ENCODER_STANDARD_MPEG4, TOPAZHP_CR_ENCODER_STANDARD);
1925 break;
1926 case IMG_STANDARD_MPEG2:
1927 /* MPEG2 */
1928 ui32SeqConfig = F_ENCODE(1, TOPAZHP_CR_WRITE_RECON_PIC)
1929 | F_ENCODE(0, TOPAZHP_CR_DEBLOCK_ENABLE)
1930 | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC0_BELOW_IN_VALID)
1931 | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC1_BELOW_IN_VALID)
1932 | F_ENCODE(0, TOPAZHP_CR_ABOVE_OUT_OF_SLICE_VALID)
1933 | F_ENCODE(((ui32Flags & ISINTERP_FLAGS) == ISINTERP_FLAGS), TOPAZHP_CR_WRITE_TEMPORAL_PIC0_BELOW_VALID)
1934 | F_ENCODE(1, TOPAZHP_CR_REF_PIC0_VALID)
1935 | F_ENCODE(0, TOPAZHP_CR_REF_PIC1_VALID)
1936 | F_ENCODE(1, TOPAZHP_CR_REF_PIC1_EQUAL_PIC0)
1937 | F_ENCODE(bFieldMode ? 1 : 0 , TOPAZHP_CR_FIELD_MODE)
1938 | F_ENCODE(ui8SwapChromas, TOPAZHP_CR_FRAME_STORE_CHROMA_SWAP)
1939 | F_ENCODE(ui32FrameStoreFormat, TOPAZHP_CR_FRAME_STORE_FORMAT)
1940 | F_ENCODE(TOPAZHP_CR_ENCODER_STANDARD_MPEG2, TOPAZHP_CR_ENCODER_STANDARD);
1941 break;
1942 case IMG_STANDARD_H263:
1943 /* H263 */
1944 ui32SeqConfig = F_ENCODE(1, TOPAZHP_CR_WRITE_RECON_PIC)
1945 | F_ENCODE(0, TOPAZHP_CR_DEBLOCK_ENABLE)
1946 | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC0_BELOW_IN_VALID)
1947 | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC1_BELOW_IN_VALID)
1948 | F_ENCODE(0, TOPAZHP_CR_ABOVE_OUT_OF_SLICE_VALID)
1949 | F_ENCODE(((ui32Flags & ISINTERP_FLAGS) == ISINTERP_FLAGS), TOPAZHP_CR_WRITE_TEMPORAL_PIC0_BELOW_VALID)
1950 | F_ENCODE(0, TOPAZHP_CR_REF_PIC0_VALID)
1951 | F_ENCODE(0, TOPAZHP_CR_REF_PIC1_VALID)
1952 | F_ENCODE(1, TOPAZHP_CR_REF_PIC1_EQUAL_PIC0)
1953 | F_ENCODE(0, TOPAZHP_CR_FIELD_MODE)
1954 | F_ENCODE(ui8SwapChromas, TOPAZHP_CR_FRAME_STORE_CHROMA_SWAP)
1955 | F_ENCODE(ui32FrameStoreFormat, TOPAZHP_CR_FRAME_STORE_FORMAT)
1956 | F_ENCODE(TOPAZHP_CR_ENCODER_STANDARD_H263, TOPAZHP_CR_ENCODER_STANDARD);
1957 break;
1958 }
1959
1960 if (bIsBPicture) {
1961 ui32SeqConfig |= F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC1_BELOW_IN_VALID)
1962 | F_ENCODE(0, TOPAZHP_CR_WRITE_TEMPORAL_PIC1_BELOW_VALID)
1963 | F_ENCODE(1, TOPAZHP_CR_REF_PIC1_VALID)
1964 | F_ENCODE(1, TOPAZHP_CR_TEMPORAL_COL_IN_VALID);
1965 }
1966
1967 if (ctx->ui8EnableSelStatsFlags & ESF_FIRST_STAGE_STATS) {
1968 ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_WRITE_MB_FIRST_STAGE_VALID);
1969 }
1970
1971 if (ctx->ui8EnableSelStatsFlags & ESF_MP_BEST_MB_DECISION_STATS ||
1972 ctx->ui8EnableSelStatsFlags & ESF_MP_BEST_MOTION_VECTOR_STATS) {
1973 ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_BEST_MULTIPASS_OUT_VALID);
1974
1975 if (!(ctx->ui8EnableSelStatsFlags & ESF_MP_BEST_MOTION_VECTOR_STATS)) {
1976 ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_BEST_MVS_OUT_DISABLE);// 64 Byte Best Multipass Motion Vector output disabled by default
1977 }
1978 }
1979
1980 if (ctx->bEnableInpCtrl) {
1981 ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_MB_CONTROL_IN_VALID);
1982 }
1983
1984 if (eSliceType == IMG_FRAME_IDR) {
1985 ctx->sBiasTables.ui32SeqConfigInit = ui32SeqConfig;
1986 }
1987
1988 tng__save_slice_params_template(ctx, ui32SliceBufIdx, eSliceType,
1989 ui32IPEControl, ui32Flags, ui32SliceConfig, ui32SeqConfig, ui32StreamIndex);
1990
1991 return 0;
1992 }
1993
tng__mpeg4_generate_pic_hdr_template(context_ENC_p ctx,IMG_FRAME_TEMPLATE_TYPE ui8SliceType,IMG_UINT8 ui8Search_range)1994 void tng__mpeg4_generate_pic_hdr_template(
1995 context_ENC_p ctx,
1996 IMG_FRAME_TEMPLATE_TYPE ui8SliceType,
1997 IMG_UINT8 ui8Search_range)
1998 {
1999 context_ENC_mem *ps_mem = &(ctx->ctx_mem[ctx->ui32StreamID]);
2000 MTX_HEADER_PARAMS * pPicHeaderMem;
2001 VOP_CODING_TYPE eVop_Coding_Type;
2002 IMG_BOOL8 b8IsVopCoded;
2003 IMG_UINT8 ui8OriginalSliceType = ui8SliceType;
2004
2005 /* MPEG4: We do not support B-frames at the moment, so we use a spare slot, to store a template for the skipped frame */
2006 if (ui8SliceType == IMG_FRAME_INTER_B)
2007 {
2008 ui8SliceType = IMG_FRAME_INTER_P;
2009 b8IsVopCoded = IMG_FALSE;
2010 } else {
2011 b8IsVopCoded = IMG_TRUE;
2012 }
2013
2014 eVop_Coding_Type = (ui8SliceType == IMG_FRAME_INTER_P) ? P_FRAME : I_FRAME;
2015
2016 psb_buffer_map(&(ps_mem->bufs_pic_template), &(ps_mem->bufs_pic_template.virtual_addr));
2017 if (ps_mem->bufs_pic_template.virtual_addr == NULL) {
2018 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping pic template\n", __FUNCTION__);
2019 return ;
2020 }
2021
2022 pPicHeaderMem = (MTX_HEADER_PARAMS *)((IMG_UINT8*)(ps_mem->bufs_pic_template.virtual_addr + (ctx->ctx_mem_size.pic_template * ui8OriginalSliceType)));
2023 //todo fix time resolution
2024 tng__MPEG4_notforsims_prepare_vop_header(pPicHeaderMem, b8IsVopCoded, ui8Search_range, eVop_Coding_Type);
2025 psb_buffer_unmap(&(ps_mem->bufs_pic_template));
2026
2027 }
2028
tng__h263_generate_pic_hdr_template(context_ENC_p ctx,IMG_FRAME_TEMPLATE_TYPE eFrameType,IMG_UINT16 ui16Width,IMG_UINT16 ui16Heigh)2029 void tng__h263_generate_pic_hdr_template(
2030 context_ENC_p ctx,
2031 IMG_FRAME_TEMPLATE_TYPE eFrameType,
2032 IMG_UINT16 ui16Width,
2033 IMG_UINT16 ui16Heigh)
2034
2035 {
2036 context_ENC_mem *ps_mem = &(ctx->ctx_mem[ctx->ui32StreamID]);
2037 MTX_HEADER_PARAMS * pPicHeaderMem = NULL;
2038 H263_PICTURE_CODING_TYPE ePictureCodingType = ((eFrameType == IMG_FRAME_INTRA)|| (eFrameType == IMG_FRAME_IDR)) ? I_FRAME : P_FRAME;
2039
2040 psb_buffer_map(&(ps_mem->bufs_pic_template), &(ps_mem->bufs_pic_template.virtual_addr));
2041 if (ps_mem->bufs_pic_template.virtual_addr == NULL) {
2042 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping pic template\n", __FUNCTION__);
2043 return ;
2044 }
2045
2046 pPicHeaderMem = (MTX_HEADER_PARAMS *)((IMG_UINT8*)(ps_mem->bufs_pic_template.virtual_addr + (ctx->ctx_mem_size.pic_template * eFrameType)));
2047
2048 IMG_UINT8 ui8FrameRate = (IMG_UINT8)ctx->sRCParams.ui32FrameRate;
2049
2050 // Get a pointer to the memory the header will be written to
2051 tng__H263_notforsims_prepare_video_pictureheader(
2052 pPicHeaderMem,
2053 ePictureCodingType,
2054 ctx->ui8H263SourceFormat,
2055 ui8FrameRate,
2056 ui16Width,
2057 ui16Heigh);
2058
2059 psb_buffer_unmap(&(ps_mem->bufs_pic_template));
2060
2061 }
2062
2063
tng__MPEG4ES_send_seq_header(context_ENC_p ctx,IMG_UINT32 ui32StreamIndex)2064 static void tng__MPEG4ES_send_seq_header(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
2065 {
2066 context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
2067 tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
2068
2069 psb_buffer_map(&(ps_mem->bufs_seq_header), &(ps_mem->bufs_seq_header.virtual_addr));
2070 if (ps_mem->bufs_seq_header.virtual_addr == NULL) {
2071 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping seq template\n", __FUNCTION__);
2072 return ;
2073 }
2074
2075 tng__MPEG4_prepare_sequence_header(ps_mem->bufs_seq_header.virtual_addr,
2076 IMG_FALSE,//FIXME: Zhaohan bFrame
2077 ctx->ui8ProfileIdc,//profile
2078 ctx->ui8LevelIdc,//ui8Profile_lvl_indication
2079 3,//ui8Fixed_vop_time_increment
2080 ctx->obj_context->picture_width,//ui8Fixed_vop_time_increment
2081 ctx->obj_context->picture_height,//ui32Picture_Height_Pixels
2082 NULL,//VBVPARAMS
2083 ctx->ui32VopTimeResolution);
2084 psb_buffer_unmap(&(ps_mem->bufs_seq_header));
2085
2086 cmdbuf->cmd_idx_saved[TNG_CMDBUF_SEQ_HEADER_IDX] = cmdbuf->cmd_idx;
2087 }
2088
tng__H264ES_send_seq_header(context_ENC_p ctx,IMG_UINT32 ui32StreamIndex)2089 static void tng__H264ES_send_seq_header(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
2090 {
2091 context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
2092 tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
2093 IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
2094 H264_VUI_PARAMS *psVuiParams = &(ctx->sVuiParams);
2095
2096 // memset(psVuiParams, 0, sizeof(H264_VUI_PARAMS));
2097
2098 if (psRCParams->eRCMode != IMG_RCMODE_NONE) {
2099 psVuiParams->vui_flag = 1;
2100 if (psVuiParams->num_units_in_tick == 0 || psVuiParams->Time_Scale == 0) {
2101 psVuiParams->num_units_in_tick = 1;
2102 psVuiParams->Time_Scale = psRCParams->ui32FrameRate * 2;
2103 }
2104 psVuiParams->bit_rate_value_minus1 = psRCParams->ui32BitsPerSecond / 64 - 1;
2105 psVuiParams->cbp_size_value_minus1 = psRCParams->ui32BufferSize / 64 - 1;
2106 psVuiParams->CBR = ((psRCParams->eRCMode == IMG_RCMODE_CBR) && (!psRCParams->bDisableBitStuffing)) ? 1 : 0;
2107 psVuiParams->initial_cpb_removal_delay_length_minus1 = BPH_SEI_NAL_INITIAL_CPB_REMOVAL_DELAY_SIZE - 1;
2108 psVuiParams->cpb_removal_delay_length_minus1 = PTH_SEI_NAL_CPB_REMOVAL_DELAY_SIZE - 1;
2109 psVuiParams->dpb_output_delay_length_minus1 = PTH_SEI_NAL_DPB_OUTPUT_DELAY_SIZE - 1;
2110 psVuiParams->time_offset_length = 24;
2111 }
2112 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s psVuiParams->vui_flag = %d\n", __FUNCTION__, psVuiParams->vui_flag);
2113
2114 psb_buffer_map(&(ps_mem->bufs_seq_header), &(ps_mem->bufs_seq_header.virtual_addr));
2115 if (ps_mem->bufs_seq_header.virtual_addr == NULL) {
2116 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping seq header\n", __FUNCTION__);
2117 return ;
2118 }
2119
2120 tng__H264ES_prepare_sequence_header(
2121 ps_mem->bufs_seq_header.virtual_addr,
2122 &(ctx->sVuiParams),
2123 &(ctx->sCropParams),
2124 ctx->ui16Width, //ui8_picture_width_in_mbs
2125 ctx->ui16PictureHeight, //ui8_picture_height_in_mbs
2126 ctx->ui32CustomQuantMask, //0, ui8_custom_quant_mask
2127 ctx->ui8ProfileIdc, //ui8_profile
2128 ctx->ui8LevelIdc, //ui8_level
2129 ctx->ui8FieldCount, //1, ui8_field_count
2130 ctx->ui8MaxNumRefFrames, //1, ui8_max_num_ref_frames
2131 ctx->bPpsScaling, //0 ui8_pps_scaling_cnt
2132 ctx->bUseDefaultScalingList, //0, b_use_default_scaling_list
2133 ctx->bEnableLossless, //0, blossless
2134 ctx->bArbitrarySO
2135 );
2136 psb_buffer_unmap(&(ps_mem->bufs_seq_header));
2137
2138 if (ctx->bEnableMVC) {
2139 psb_buffer_map(&(ps_mem->bufs_sub_seq_header), &(ps_mem->bufs_sub_seq_header.virtual_addr));
2140 if (ps_mem->bufs_sub_seq_header.virtual_addr == NULL) {
2141 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping sub seq header\n", __FUNCTION__);
2142 return ;
2143 }
2144 tng__H264ES_prepare_mvc_sequence_header(
2145 ps_mem->bufs_sub_seq_header.virtual_addr,
2146 &(ctx->sCropParams),
2147 ctx->ui16Width, //ui8_picture_width_in_mbs
2148 ctx->ui16PictureHeight, //ui8_picture_height_in_mbs
2149 ctx->ui32CustomQuantMask, //0, ui8_custom_quant_mask
2150 ctx->ui8ProfileIdc, //ui8_profile
2151 ctx->ui8LevelIdc, //ui8_level
2152 ctx->ui8FieldCount, //1, ui8_field_count
2153 ctx->ui8MaxNumRefFrames, //1, ui8_max_num_ref_frames
2154 ctx->bPpsScaling, //0 ui8_pps_scaling_cnt
2155 ctx->bUseDefaultScalingList, //0, b_use_default_scaling_list
2156 ctx->bEnableLossless, //0, blossless
2157 ctx->bArbitrarySO
2158 );
2159 psb_buffer_unmap(&(ps_mem->bufs_sub_seq_header));
2160 }
2161
2162 cmdbuf->cmd_idx_saved[TNG_CMDBUF_SEQ_HEADER_IDX] = cmdbuf->cmd_idx;
2163
2164 return ;
2165 }
2166
tng__H264ES_send_pic_header(context_ENC_p ctx,IMG_UINT32 ui32StreamIndex)2167 static void tng__H264ES_send_pic_header(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
2168 {
2169 context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
2170 IMG_BOOL bDepViewPPS = IMG_FALSE;
2171
2172 if ((ctx->bEnableMVC) && (ctx->ui16MVCViewIdx != 0) &&
2173 (ctx->ui16MVCViewIdx != (IMG_UINT16)(NON_MVC_VIEW))) {
2174 bDepViewPPS = IMG_TRUE;
2175 }
2176
2177 psb_buffer_map(&(ps_mem->bufs_pic_template), &(ps_mem->bufs_pic_template.virtual_addr));
2178 if (ps_mem->bufs_pic_template.virtual_addr == NULL) {
2179 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping pic template\n", __FUNCTION__);
2180 return ;
2181 }
2182
2183 tng__H264ES_prepare_picture_header(
2184 ps_mem->bufs_pic_template.virtual_addr,
2185 ctx->bCabacEnabled,
2186 ctx->bH2648x8Transform, //IMG_BOOL b_8x8transform,
2187 ctx->bH264IntraConstrained, //IMG_BOOL bIntraConstrained,
2188 0, //IMG_INT8 i8CQPOffset,
2189 0, //IMG_BOOL bWeightedPrediction,
2190 0, //IMG_UINT8 ui8WeightedBiPred,
2191 bDepViewPPS, //IMG_BOOL bMvcPPS,
2192 0, //IMG_BOOL bScalingMatrix,
2193 0 //IMG_BOOL bScalingLists
2194 );
2195
2196 psb_buffer_unmap(&(ps_mem->bufs_pic_template));
2197 return ;
2198 }
2199
tng__H264ES_send_hrd_header(context_ENC_p ctx,IMG_UINT32 ui32StreamIndex)2200 static void tng__H264ES_send_hrd_header(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
2201 {
2202 unsigned int ui32nal_initial_cpb_removal_delay;
2203 unsigned int ui32nal_initial_cpb_removal_delay_offset;
2204 uint32_t ui32cpb_removal_delay;
2205 IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
2206 context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
2207 H264_VUI_PARAMS *psVuiParams = &(ctx->sVuiParams);
2208 IMG_UINT8 aui8clocktimestampflag[1];
2209 aui8clocktimestampflag[0] = IMG_FALSE;
2210
2211 ui32nal_initial_cpb_removal_delay =
2212 90000 * (1.0 * psRCParams->i32InitialDelay / psRCParams->ui32BitsPerSecond);
2213 ui32nal_initial_cpb_removal_delay_offset =
2214 90000 * (1.0 * ctx->buffer_size / psRCParams->ui32BitsPerSecond)
2215 - ui32nal_initial_cpb_removal_delay;
2216
2217 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert SEI buffer period message with "
2218 "ui32nal_initial_cpb_removal_delay(%d) and "
2219 "ui32nal_initial_cpb_removal_delay_offset(%d)\n",
2220 ui32nal_initial_cpb_removal_delay,
2221 ui32nal_initial_cpb_removal_delay_offset);
2222
2223 psb_buffer_map(&(ps_mem->bufs_sei_header), &(ps_mem->bufs_sei_header.virtual_addr));
2224 if (ps_mem->bufs_sei_header.virtual_addr == NULL) {
2225 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping sei header\n", __FUNCTION__);
2226 return ;
2227 }
2228
2229 if ((!ctx->bEnableMVC) || (ctx->ui16MVCViewIdx == 0)) {
2230 tng__H264ES_prepare_AUD_header(ps_mem->bufs_sei_header.virtual_addr);
2231 }
2232
2233 tng__H264ES_prepare_SEI_buffering_period_header(
2234 ps_mem->bufs_sei_header.virtual_addr + (ctx->ctx_mem_size.sei_header),
2235 0,// ui8cpb_cnt_minus1,
2236 psVuiParams->initial_cpb_removal_delay_length_minus1+1, //ui8initial_cpb_removal_delay_length,
2237 1, //ui8NalHrdBpPresentFlag,
2238 ui32nal_initial_cpb_removal_delay, // ui32nal_initial_cpb_removal_delay,
2239 ui32nal_initial_cpb_removal_delay_offset, //ui32nal_initial_cpb_removal_delay_offset,
2240 0, //ui8VclHrdBpPresentFlag - CURRENTLY HARD CODED TO ZERO IN TOPAZ
2241 NOT_USED_BY_TOPAZ, // ui32vcl_initial_cpb_removal_delay, (not used when ui8VclHrdBpPresentFlag = 0)
2242 NOT_USED_BY_TOPAZ); // ui32vcl_initial_cpb_removal_delay_offset (not used when ui8VclHrdBpPresentFlag = 0)
2243
2244 /* ui32cpb_removal_delay is zero for 1st frame and will be reset
2245 * after a IDR frame */
2246 if (ctx->ui32FrameCount[ui32StreamIndex] == 0) {
2247 if (ctx->ui32RawFrameCount == 0)
2248 ui32cpb_removal_delay = 0;
2249 else
2250 ui32cpb_removal_delay =
2251 ctx->ui32IdrPeriod * ctx->ui32IntraCnt * 2;
2252 } else
2253 ui32cpb_removal_delay = 2 * ctx->ui32FrameCount[ui32StreamIndex];
2254
2255 tng__H264ES_prepare_SEI_picture_timing_header(
2256 ps_mem->bufs_sei_header.virtual_addr + (ctx->ctx_mem_size.sei_header * 2),
2257 1, //ui8CpbDpbDelaysPresentFlag,
2258 psVuiParams->cpb_removal_delay_length_minus1, //cpb_removal_delay_length_minus1,
2259 psVuiParams->dpb_output_delay_length_minus1, //dpb_output_delay_length_minus1,
2260 ui32cpb_removal_delay, //ui32cpb_removal_delay,
2261 2, //ui32dpb_output_delay,
2262 0, //ui8pic_struct_present_flag (contained in the sequence header, Topaz hard-coded default to 0)
2263 NOT_USED_BY_TOPAZ, //ui8pic_struct, (not used when ui8pic_struct_present_flag = 0)
2264 NOT_USED_BY_TOPAZ, //NumClockTS, (not used when ui8pic_struct_present_flag = 0)
2265 aui8clocktimestampflag, //abclock_timestamp_flag, (not used when ui8pic_struct_present_flag = 0)
2266 NOT_USED_BY_TOPAZ, //ui8full_timestamp_flag, (not used when ui8pic_struct_present_flag = 0)
2267 NOT_USED_BY_TOPAZ, //ui8seconds_flag, (not used when ui8pic_struct_present_flag = 0)
2268 NOT_USED_BY_TOPAZ, //ui8minutes_flag, (not used when ui8pic_struct_present_flag = 0)
2269 NOT_USED_BY_TOPAZ, //ui8hours_flag, (not used when ui8pic_struct_present_flag = 0)
2270 NOT_USED_BY_TOPAZ, //seconds_value, (not used when ui8pic_struct_present_flag = 0)
2271 NOT_USED_BY_TOPAZ, //minutes_value, (not used when ui8pic_struct_present_flag = 0)
2272 NOT_USED_BY_TOPAZ, //hours_value, (not used when ui8pic_struct_present_flag = 0)
2273 NOT_USED_BY_TOPAZ, //ct_type (2=Unknown) See TRM Table D 2 ?Mapping of ct_type to source picture scan (not used when ui8pic_struct_present_flag = 0)
2274 NOT_USED_BY_TOPAZ, //nuit_field_based_flag, (not used when ui8pic_struct_present_flag = 0)
2275 NOT_USED_BY_TOPAZ, //counting_type (See TRM Table D 3 ?Definition of counting_type values) (not used when ui8pic_struct_present_flag = 0)
2276 NOT_USED_BY_TOPAZ, //ui8discontinuity_flag, (not used when ui8pic_struct_present_flag = 0)
2277 NOT_USED_BY_TOPAZ, //ui8cnt_dropped_flag, (not used when ui8pic_struct_present_flag = 0)
2278 NOT_USED_BY_TOPAZ, //n_frames, (not used when ui8pic_struct_present_flag = 0)
2279 NOT_USED_BY_TOPAZ, //time_offset_length, (not used when ui8pic_struct_present_flag = 0)
2280 NOT_USED_BY_TOPAZ); //time_offset (not used when ui8pic_struct_present_flag = 0)
2281 psb_buffer_unmap(&(ps_mem->bufs_sei_header));
2282
2283 return ;
2284 }
2285
tng__generate_slice_params_template(context_ENC_p ctx,IMG_UINT32 slice_buf_idx,IMG_UINT32 slice_type,IMG_UINT32 ui32StreamIndex)2286 static void tng__generate_slice_params_template(
2287 context_ENC_p ctx,
2288 IMG_UINT32 slice_buf_idx,
2289 IMG_UINT32 slice_type,
2290 IMG_UINT32 ui32StreamIndex
2291 )
2292 {
2293 context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
2294 IMG_UINT8 *slice_mem_temp_p = NULL;
2295 IMG_UINT32 ui32SliceHeight = 0;
2296 IMG_FRAME_TEMPLATE_TYPE slice_temp_type = (IMG_FRAME_TEMPLATE_TYPE)slice_type;
2297 IMG_FRAME_TEMPLATE_TYPE buf_idx = (IMG_FRAME_TEMPLATE_TYPE)slice_buf_idx;
2298
2299 if (ctx->ui8SlicesPerPicture != 0)
2300 ui32SliceHeight = ctx->ui16PictureHeight / ctx->ui8SlicesPerPicture;
2301 else
2302 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s slice height\n", __FUNCTION__);
2303
2304 ui32SliceHeight &= ~15;
2305
2306 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG ui8DeblockIDC = %x\n", __FUNCTION__, ctx->ui8DeblockIDC );
2307 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG ui32SliceHeight = %x\n", __FUNCTION__, ui32SliceHeight );
2308 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG bIsInterlaced = %x\n", __FUNCTION__, ctx->bIsInterlaced );
2309 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG iFineYSearchSize = %x\n", __FUNCTION__, ctx->iFineYSearchSize);
2310
2311 tng__prepare_encode_sliceparams(
2312 ctx,
2313 slice_buf_idx,
2314 slice_temp_type,
2315 0, // ui16CurrentRow,
2316 ui32SliceHeight,
2317 ctx->ui8DeblockIDC, // uiDeblockIDC
2318 ctx->bIsInterlaced, // bFieldMode
2319 ctx->iFineYSearchSize,
2320 ui32StreamIndex
2321 );
2322
2323 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG bCabacEnabled = %x\n", __FUNCTION__, ctx->bCabacEnabled );
2324 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG ui16MVCViewIdx = %x\n", __FUNCTION__, ctx->ui16MVCViewIdx);
2325
2326 if(ctx->bEnableMVC)
2327 ctx->ui16MVCViewIdx = (IMG_UINT16)ui32StreamIndex;
2328
2329 if (ps_mem->bufs_slice_template.virtual_addr == NULL) {
2330 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping slice template\n", __FUNCTION__);
2331 return ;
2332 }
2333
2334 slice_mem_temp_p = (IMG_UINT8*)(ps_mem->bufs_slice_template.virtual_addr + (ctx->ctx_mem_size.slice_template * buf_idx));
2335 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: addr 0x%08x, virtual 0x%08x, size = 0x%08x, buf_idx = %x\n",
2336 __FUNCTION__, slice_mem_temp_p, ps_mem->bufs_slice_template.virtual_addr, ctx->ctx_mem_size.slice_template, buf_idx);
2337
2338 /* Prepare Slice Header Template */
2339 switch (ctx->eStandard) {
2340 case IMG_STANDARD_NONE:
2341 case IMG_STANDARD_JPEG:
2342 case IMG_STANDARD_MPEG4:
2343 break;
2344 case IMG_STANDARD_H264:
2345 //H264_NOTFORSIMS_PrepareSliceHeader
2346 tng__H264ES_notforsims_prepare_sliceheader(
2347 slice_mem_temp_p,
2348 slice_temp_type,
2349 ctx->ui8DeblockIDC,
2350 0, // ui32FirstMBAddress
2351 0, // uiMBSkipRun
2352 ctx->bCabacEnabled,
2353 ctx->bIsInterlaced,
2354 ctx->ui16MVCViewIdx, //(IMG_UINT16)(NON_MVC_VIEW);
2355 IMG_FALSE // bIsLongTermRef
2356 );
2357 break;
2358
2359 case IMG_STANDARD_H263:
2360 tng__H263ES_notforsims_prepare_gobsliceheader(slice_mem_temp_p);
2361 break;
2362
2363 case IMG_STANDARD_MPEG2:
2364 tng__MPEG2_prepare_sliceheader(slice_mem_temp_p);
2365 break;
2366 }
2367
2368 psb_buffer_unmap(&(ps_mem->bufs_slice_template));
2369
2370 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: end \n", __FUNCTION__);
2371
2372 return ;
2373 }
2374
2375 //H264_PrepareTemplates
tng__prepare_templates(context_ENC_p ctx,IMG_UINT32 ui32StreamIndex)2376 static VAStatus tng__prepare_templates(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
2377 {
2378 IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
2379 PIC_PARAMS *psPicParams = &(ctx->sPicParams);
2380 IN_RC_PARAMS* psInParams = &(psPicParams->sInParams);
2381 psPicParams->ui32Flags = 0;
2382
2383 tng__prepare_mv_estimates(ctx, ui32StreamIndex);
2384
2385 switch (ctx->eStandard) {
2386 case IMG_STANDARD_H263:
2387 psPicParams->ui32Flags |= ISH263_FLAGS;
2388 break;
2389 case IMG_STANDARD_MPEG4:
2390 psPicParams->ui32Flags |= ISMPEG4_FLAGS;
2391 break;
2392 case IMG_STANDARD_MPEG2:
2393 psPicParams->ui32Flags |= ISMPEG2_FLAGS;
2394 break;
2395 default:
2396 break;
2397 }
2398
2399 if (psRCParams->eRCMode) {
2400 psPicParams->ui32Flags |= ISRC_FLAGS;
2401 tng__setup_rcdata(ctx);
2402 } else {
2403 psInParams->ui8SeInitQP = psRCParams->ui32InitialQp;
2404 psInParams->ui8MBPerRow = (ctx->ui16Width >> 4);
2405 psInParams->ui16MBPerFrm = (ctx->ui16Width >> 4) * (ctx->ui16PictureHeight >> 4);
2406 psInParams->ui16MBPerBU = psRCParams->ui32BUSize;
2407 psInParams->ui16BUPerFrm = (psInParams->ui16MBPerFrm) / psRCParams->ui32BUSize;
2408 ctx->ui32KickSize = psInParams->ui16MBPerBU;
2409 }
2410
2411 // Prepare Slice header templates
2412 tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_IDR, (IMG_UINT32)IMG_FRAME_IDR, ui32StreamIndex);
2413 tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_INTRA, (IMG_UINT32)IMG_FRAME_INTRA, ui32StreamIndex);
2414 tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_INTER_P, (IMG_UINT32)IMG_FRAME_INTER_P, ui32StreamIndex);
2415 switch(ctx->eStandard) {
2416 case IMG_STANDARD_H264:
2417 tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_INTER_B, (IMG_UINT32)IMG_FRAME_INTER_B, ui32StreamIndex);
2418 if (ctx->bEnableMVC)
2419 tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_INTER_P_IDR, (IMG_UINT32)IMG_FRAME_INTER_P_IDR, ui32StreamIndex);
2420 tng__H264ES_send_seq_header(ctx, 0);
2421 tng__H264ES_send_pic_header(ctx, 0);
2422 if (ctx->bInsertHRDParams)
2423 tng__H264ES_send_hrd_header(ctx, 0);
2424 break;
2425 case IMG_STANDARD_H263:
2426 tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_INTER_B, (IMG_UINT32)IMG_FRAME_INTER_B, ui32StreamIndex);
2427 /* Here H263 uses the actual width and height */
2428 tng__h263_generate_pic_hdr_template(ctx, IMG_FRAME_IDR, ctx->h263_actual_width, ctx->h263_actual_height);
2429 tng__h263_generate_pic_hdr_template(ctx, IMG_FRAME_INTRA, ctx->h263_actual_width, ctx->h263_actual_height);
2430 tng__h263_generate_pic_hdr_template(ctx, IMG_FRAME_INTER_P, ctx->h263_actual_width, ctx->h263_actual_height);
2431 break;
2432 case IMG_STANDARD_MPEG4:
2433 tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_INTER_B, (IMG_UINT32)IMG_FRAME_INTER_P, ui32StreamIndex);
2434 tng__mpeg4_generate_pic_hdr_template(ctx, IMG_FRAME_IDR, 4);
2435 tng__mpeg4_generate_pic_hdr_template(ctx, IMG_FRAME_INTRA, 4);
2436 tng__mpeg4_generate_pic_hdr_template(ctx, IMG_FRAME_INTER_P, 4);
2437 tng__mpeg4_generate_pic_hdr_template(ctx, IMG_FRAME_INTER_B, 4);
2438 break;
2439 default:
2440 break;
2441 }
2442
2443 //FIXME: Zhaohan tng__mpeg2/mpeg4_generate_pic_hdr_template(IMG_FRAME_IDR\IMG_FRAME_INTRA\IMG_FRAME_INTER_P\IMG_FRAME_INTER_B);
2444
2445 /*
2446 else {
2447 slice_mem_temp_p = (IMG_UINT8*)cmdbuf->slice_mem_p + (((IMG_UINT32)IMG_FRAME_INTER_P_IDR) * cmdbuf->mem_size);
2448 memset(slice_mem_temp_p, 0, 128);
2449 }
2450 */
2451 // Prepare Pic Params Templates
2452 tng__adjust_picflags(ctx, psRCParams, IMG_TRUE, &(ctx->ui32FirstPicFlags));
2453 tng__adjust_picflags(ctx, psRCParams, IMG_FALSE, &(ctx->ui32NonFirstPicFlags));
2454
2455 return VA_STATUS_SUCCESS;
2456 }
2457
2458 #if INPUT_SCALER_SUPPORTED
VIDEO_CalculateBessel0(IMG_FLOAT fX)2459 static IMG_FLOAT VIDEO_CalculateBessel0 (IMG_FLOAT fX)
2460 {
2461 IMG_FLOAT fAX, fY;
2462
2463 fAX = (IMG_FLOAT)IMG_FABS(fX);
2464
2465 if (fAX < 3.75) {
2466 fY = (IMG_FLOAT)(fX / 3.75);
2467 fY *= fY;
2468
2469 return (IMG_FLOAT)(1.0 + fY *
2470 (3.5156229 + fY *
2471 (3.0899424 + fY *
2472 (1.2067492 + fY *
2473 (0.2659732 + fY *
2474 (0.360768e-1 + fY * 0.45813e-2))))));
2475 }
2476
2477 fY = (IMG_FLOAT)(3.75 / fAX);
2478
2479 return (IMG_FLOAT)((IMG_EXP(fAX) / IMG_SQRT(fAX)) *
2480 (0.39894228 + fY *
2481 (0.1328592e-1 + fY *
2482 (0.225319e-2 + fY *
2483 (-0.157565e-2 + fY *
2484 (0.916281e-2 + fY *
2485 (-0.2057706e-1 + fY *
2486 (0.2635537e-1 + fY *
2487 (-0.1647633e-1 + fY * 0.392377e-2)))))))));
2488 }
2489
VIDEO_SincFunc(IMG_FLOAT fInput,IMG_FLOAT fScale)2490 static IMG_FLOAT VIDEO_SincFunc (IMG_FLOAT fInput, IMG_FLOAT fScale)
2491 {
2492 IMG_FLOAT fX;
2493 IMG_FLOAT fKaiser;
2494
2495 /* Kaiser window */
2496 fX = fInput / (4.0f / 2.0f) - 1.0f;
2497 fX = (IMG_FLOAT)IMG_SQRT(1.0f - fX * fX);
2498 fKaiser = VIDEO_CalculateBessel0(2.0f * fX) / VIDEO_CalculateBessel0(2.0f);
2499
2500 /* Sinc function */
2501 fX = 4.0f / 2.0f - fInput;
2502 if (fX == 0) {
2503 return fKaiser;
2504 }
2505
2506 fX *= 0.9f * fScale * 3.1415926535897f;
2507
2508 return fKaiser * (IMG_FLOAT)(IMG_SIN(fX) / fX);
2509 }
2510
VIDEO_CalcCoefs_FromPitch(IMG_FLOAT fPitch,IMG_UINT8 aui8Table[4][16])2511 static void VIDEO_CalcCoefs_FromPitch (IMG_FLOAT fPitch, IMG_UINT8 aui8Table[4][16])
2512 {
2513 /* Based on sim code */
2514 /* The function is symmetrical, so we only need to calculate the first half of the taps, and the middle value. */
2515
2516 IMG_FLOAT fScale;
2517 IMG_UINT32 ui32I, ui32Tap;
2518 IMG_FLOAT afTable[4][16];
2519 IMG_INT32 i32Total;
2520 IMG_FLOAT fTotal;
2521 IMG_INT32 i32MiddleTap, i32MiddleI; /* Mirrored / middle Values for I and T */
2522
2523 if (fPitch < 1.0f) {
2524 fScale = 1.0f;
2525 } else {
2526 fScale = 1.0f / fPitch;
2527 }
2528
2529 for (ui32I = 0; ui32I < 16; ui32I++) {
2530 for (ui32Tap = 0; ui32Tap < 4; ui32Tap++) {
2531 afTable[ui32Tap][ui32I] = VIDEO_SincFunc(((IMG_FLOAT)ui32Tap) + ((IMG_FLOAT)ui32I) / 16.0f, fScale);
2532 }
2533 }
2534
2535 for (ui32Tap = 0; ui32Tap < 2; ui32Tap++) {
2536 for (ui32I = 0; ui32I < 16; ui32I++) {
2537 /* Copy the table around the centre point */
2538 i32MiddleTap = (3 - ui32Tap) + (16 - ui32I) / 16;
2539 i32MiddleI = (16 - ui32I) & 15;
2540 if ((IMG_UINT32)i32MiddleTap < 4) {
2541 afTable[i32MiddleTap][i32MiddleI] = afTable[ui32Tap][ui32I];
2542 }
2543 }
2544 }
2545
2546 /* The middle value */
2547 afTable[2][0] = VIDEO_SincFunc(2.0f, fScale);
2548
2549 /* Normalize this interpolation point, and convert to 2.6 format, truncating the result */
2550 for (ui32I = 0; ui32I < 16; ui32I++) {
2551 fTotal = 0.0f;
2552 i32Total = 0;
2553
2554 for (ui32Tap = 0; ui32Tap < 4; ui32Tap++) {
2555 fTotal += afTable[ui32Tap][ui32I];
2556 }
2557
2558 for (ui32Tap = 0; ui32Tap < 4; ui32Tap++) {
2559 aui8Table[ui32Tap][ui32I] = (IMG_UINT8)((afTable[ui32Tap][ui32I] * 64.0f) / fTotal);
2560 i32Total += aui8Table[ui32Tap][ui32I];
2561 }
2562
2563 if (ui32I <= 8) { /* normalize any floating point errors */
2564 i32Total -= 64;
2565 if (ui32I == 8) {
2566 i32Total /= 2;
2567 }
2568 /* Subtract the error from the I Point in the first tap ( this will not get
2569 mirrored, as it would go off the end). */
2570 aui8Table[0][ui32I] = (IMG_UINT8)(aui8Table[0][ui32I] - (IMG_UINT8)i32Total);
2571 }
2572 }
2573
2574 /* Copy the normalised table around the centre point */
2575 for (ui32Tap = 0; ui32Tap < 2; ui32Tap++) {
2576 for (ui32I = 0; ui32I < 16; ui32I++) {
2577 i32MiddleTap = (3 - ui32Tap) + (16 - ui32I) / 16;
2578 i32MiddleI = (16 - ui32I) & 15;
2579 if ((IMG_UINT32)i32MiddleTap < 4) {
2580 aui8Table[i32MiddleTap][i32MiddleI] = aui8Table[ui32Tap][ui32I];
2581 }
2582 }
2583 }
2584 return ;
2585 }
2586 #endif
2587
tng__setvideo_params(context_ENC_p ctx,IMG_UINT32 ui32StreamIndex)2588 static void tng__setvideo_params(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
2589 {
2590 context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
2591 context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
2592 IMG_MTX_VIDEO_CONTEXT* psMtxEncContext = NULL;
2593 IMG_RC_PARAMS * psRCParams = &(ctx->sRCParams);
2594 //IMG_UINT16 ui16WidthInMbs = (ctx->ui16Width + 15) >> 4;
2595 //IMG_UINT16 ui16FrameHeightInMbs = (ctx->ui16FrameHeight + 15) >> 4;
2596 IMG_INT nIndex;
2597 IMG_UINT8 ui8Flag;
2598 #ifndef EXCLUDE_ADAPTIVE_ROUNDING
2599 IMG_INT32 i, j;
2600 #endif
2601
2602 psb_buffer_map(&(ps_mem->bufs_mtx_context), &(ps_mem->bufs_mtx_context.virtual_addr));
2603 if (ps_mem->bufs_mtx_context.virtual_addr == NULL) {
2604 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping slice template\n", __FUNCTION__);
2605 return ;
2606 }
2607
2608 psMtxEncContext = (IMG_MTX_VIDEO_CONTEXT*)(ps_mem->bufs_mtx_context.virtual_addr);
2609
2610 ctx->i32PicNodes = (psRCParams->b16Hierarchical ? MAX_REF_B_LEVELS : 0) + ctx->ui8RefSpacing + 4;
2611 ctx->i32MVStores = (ctx->i32PicNodes * 2);
2612 ctx->ui8SlotsInUse = psRCParams->ui16BFrames + 2;
2613
2614 psMtxEncContext->ui32InitialQp = ctx->sRCParams.ui32InitialQp;
2615 psMtxEncContext->ui32BUSize = ctx->sRCParams.ui32BUSize;
2616 psMtxEncContext->ui16CQPOffset = (ctx->sRCParams.i8QCPOffset & 0x1f) | ((ctx->sRCParams.i8QCPOffset & 0x1f) << 8);
2617 psMtxEncContext->eStandard = ctx->eStandard;
2618 psMtxEncContext->ui32WidthInMbs = ctx->ui16Width >> 4;
2619 psMtxEncContext->ui32PictureHeightInMbs = ctx->ui16PictureHeight >> 4;
2620 psMtxEncContext->bOutputReconstructed = (ps_buf->rec_surface != NULL) ? IMG_TRUE : IMG_FALSE;
2621 psMtxEncContext->ui32VopTimeResolution = ctx->ui32VopTimeResolution;
2622 psMtxEncContext->ui8MaxSlicesPerPicture = ctx->ui8SlicesPerPicture;
2623 psMtxEncContext->ui8NumPipes = ctx->ui8PipesToUse;
2624 psMtxEncContext->eFormat = ctx->eFormat;
2625
2626 psMtxEncContext->b8IsInterlaced = ctx->bIsInterlaced;
2627 psMtxEncContext->b8TopFieldFirst = ctx->bTopFieldFirst;
2628 psMtxEncContext->b8ArbitrarySO = ctx->bArbitrarySO;
2629
2630 psMtxEncContext->ui32IdrPeriod = ctx->ui32IdrPeriod * ctx->ui32IntraCnt;
2631 psMtxEncContext->ui32BFrameCount = ctx->sRCParams.ui16BFrames;
2632 psMtxEncContext->b8Hierarchical = (IMG_BOOL8) ctx->sRCParams.b16Hierarchical;
2633 psMtxEncContext->ui32IntraLoopCnt = ctx->ui32IntraCnt;
2634 psMtxEncContext->ui8RefSpacing = ctx->ui8RefSpacing;
2635 psMtxEncContext->ui32DebugCRCs = ctx->ui32DebugCRCs;
2636
2637 psMtxEncContext->ui8FirstPipe = ctx->ui8BasePipe;
2638 psMtxEncContext->ui8LastPipe = ctx->ui8BasePipe + ctx->ui8PipesToUse - 1;
2639 psMtxEncContext->ui8PipesToUseFlags = 0;
2640 ui8Flag = 0x1 << psMtxEncContext->ui8FirstPipe;
2641 for (nIndex = 0; nIndex < psMtxEncContext->ui8NumPipes; nIndex++, ui8Flag<<=1)
2642 psMtxEncContext->ui8PipesToUseFlags |= ui8Flag; //Pipes used MUST be contiguous from the BasePipe offset
2643
2644 // Only used in MPEG2, 2 bit field (0 = 8 bit, 1 = 9 bit, 2 = 10 bit and 3=11 bit precision)
2645 if (ctx->eStandard == IMG_STANDARD_MPEG2)
2646 psMtxEncContext->ui8MPEG2IntraDCPrecision = ctx->ui8MPEG2IntraDCPrecision;
2647
2648 psMtxEncContext->b16EnableMvc = ctx->bEnableMVC;
2649 psMtxEncContext->ui16MvcViewIdx = ctx->ui16MVCViewIdx;
2650 if (ctx->eStandard == IMG_STANDARD_H264)
2651 psMtxEncContext->b16NoSequenceHeaders = ctx->bNoSequenceHeaders;
2652
2653 {
2654 IMG_UINT16 ui16SrcYStride = 0, ui16SrcUVStride = 0;
2655 // 3 Components: Y, U, V
2656 ctx->ui16BufferStride = ps_buf->src_surface->psb_surface->stride;
2657 ui16SrcUVStride = ui16SrcYStride = ctx->ui16BufferStride;
2658 ctx->ui16BufferHeight = ctx->ui16FrameHeight;
2659 switch (ctx->eFormat) {
2660 case IMG_CODEC_YUV:
2661 case IMG_CODEC_PL8:
2662 case IMG_CODEC_YV12:
2663 ui16SrcUVStride = ui16SrcYStride / 2;
2664 break;
2665
2666 case IMG_CODEC_PL12: // Interleaved chroma pixels
2667 case IMG_CODEC_IMC2: // Interleaved chroma rows
2668 case IMG_CODEC_422_YUV: // Odd-numbered chroma rows unused
2669 case IMG_CODEC_422_YV12: // Odd-numbered chroma rows unused
2670 case IMG_CODEC_422_PL8: // Odd-numbered chroma rows unused
2671 case IMG_CODEC_Y0UY1V_8888: // Interleaved luma and chroma pixels
2672 case IMG_CODEC_Y0VY1U_8888: // Interleaved luma and chroma pixels
2673 case IMG_CODEC_UY0VY1_8888: // Interleaved luma and chroma pixels
2674 case IMG_CODEC_VY0UY1_8888: // Interleaved luma and chroma pixels
2675 ui16SrcUVStride = ui16SrcYStride;
2676 break;
2677
2678 case IMG_CODEC_422_IMC2: // Interleaved chroma pixels and unused odd-numbered chroma rows
2679 case IMG_CODEC_422_PL12: // Interleaved chroma rows and unused odd-numbered chroma rows
2680 ui16SrcUVStride = ui16SrcYStride * 2;
2681 break;
2682
2683 default:
2684 break;
2685 }
2686
2687 if ((ctx->bIsInterlaced) && (ctx->bIsInterleaved)) {
2688 ui16SrcYStride *= 2; // ui16SrcYStride
2689 ui16SrcUVStride *= 2; // ui16SrcUStride
2690 }
2691
2692 psMtxEncContext->ui32PicRowStride = F_ENCODE(ui16SrcYStride >> 6, TOPAZHP_CR_CUR_PIC_LUMA_STRIDE) |
2693 F_ENCODE(ui16SrcUVStride >> 6, TOPAZHP_CR_CUR_PIC_CHROMA_STRIDE);
2694 }
2695
2696 psMtxEncContext->eRCMode = ctx->sRCParams.eRCMode;
2697 psMtxEncContext->b8DisableBitStuffing = ctx->sRCParams.bDisableBitStuffing;
2698 psMtxEncContext->b8FirstPic = IMG_TRUE;
2699
2700 /*Contents Adaptive Rate Control Parameters*/
2701 psMtxEncContext->bCARC = ctx->sCARCParams.bCARC;
2702 psMtxEncContext->iCARCBaseline = ctx->sCARCParams.i32CARCBaseline;
2703 psMtxEncContext->uCARCThreshold = ctx->sCARCParams.ui32CARCThreshold;
2704 psMtxEncContext->uCARCCutoff = ctx->sCARCParams.ui32CARCCutoff;
2705 psMtxEncContext->uCARCNegRange = ctx->sCARCParams.ui32CARCNegRange;
2706 psMtxEncContext->uCARCNegScale = ctx->sCARCParams.ui32CARCNegScale;
2707 psMtxEncContext->uCARCPosRange = ctx->sCARCParams.ui32CARCPosRange;
2708 psMtxEncContext->uCARCPosScale = ctx->sCARCParams.ui32CARCPosScale;
2709 psMtxEncContext->uCARCShift = ctx->sCARCParams.ui32CARCShift;
2710 psMtxEncContext->ui32MVClip_Config = F_ENCODE(ctx->bNoOffscreenMv, TOPAZHP_CR_MVCALC_RESTRICT_PICTURE);
2711 psMtxEncContext->ui32LRITC_Tile_Use_Config = 0;
2712 psMtxEncContext->ui32LRITC_Cache_Chunk_Config = 0;
2713
2714 psMtxEncContext->ui32IPCM_0_Config = F_ENCODE(ctx->ui32CabacBinFlex, TOPAZ_VLC_CR_CABAC_BIN_FLEX) |
2715 F_ENCODE(DEFAULT_CABAC_DB_MARGIN, TOPAZ_VLC_CR_CABAC_DB_MARGIN);
2716
2717 psMtxEncContext->ui32IPCM_1_Config = F_ENCODE(3200, TOPAZ_VLC_CR_IPCM_THRESHOLD) |
2718 F_ENCODE(ctx->ui32CabacBinLimit, TOPAZ_VLC_CR_CABAC_BIN_LIMIT);
2719
2720 // leave alone until high profile and constrained modes are defined.
2721 psMtxEncContext->ui32H264CompControl = F_ENCODE((ctx->bCabacEnabled ? 0 : 1), TOPAZHP_CR_H264COMP_8X8_CAVLC);
2722
2723 psMtxEncContext->ui32H264CompControl |= F_ENCODE(ctx->bUseDefaultScalingList ? 1 : 0, TOPAZHP_CR_H264COMP_DEFAULT_SCALING_LIST);
2724
2725 psMtxEncContext->ui32H264CompControl |= F_ENCODE(ctx->bH2648x8Transform ? 1 : 0, TOPAZHP_CR_H264COMP_8X8_TRANSFORM);
2726
2727 psMtxEncContext->ui32H264CompControl |= F_ENCODE(ctx->bH264IntraConstrained ? 1 : 0, TOPAZHP_CR_H264COMP_CONSTRAINED_INTRA);
2728
2729
2730 #ifndef EXCLUDE_ADAPTIVE_ROUNDING
2731 psMtxEncContext->bMCAdaptiveRoundingDisable = ctx->bVPAdaptiveRoundingDisable;
2732 psMtxEncContext->ui32H264CompControl |= F_ENCODE(psMtxEncContext->bMCAdaptiveRoundingDisable ? 0 : 1, TOPAZHP_CR_H264COMP_ADAPT_ROUND_ENABLE);
2733
2734 if (!psMtxEncContext->bMCAdaptiveRoundingDisable)
2735 for (i = 0; i < 4; i++)
2736 for (j = 0; j < 18; j++)
2737 psMtxEncContext->ui16MCAdaptiveRoundingOffsets[j][i] = H264_ROUNDING_OFFSETS[j][i];
2738 #endif
2739
2740 if ((ctx->eStandard == IMG_STANDARD_H264) && (ctx->ui32CoreRev >= MIN_34_REV)) {
2741 psMtxEncContext->ui32H264CompControl |= F_ENCODE(USE_VCM_HW_SUPPORT, TOPAZHP_CR_H264COMP_VIDEO_CONF_ENABLE);
2742 }
2743
2744 psMtxEncContext->ui32H264CompControl |=
2745 F_ENCODE(ctx->ui16UseCustomScalingLists & 0x01 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_4X4_INTRA_LUMA_ENABLE)
2746 | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x02 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_4X4_INTRA_CB_ENABLE)
2747 | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x04 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_4X4_INTRA_CR_ENABLE)
2748 | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x08 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_4X4_INTER_LUMA_ENABLE)
2749 | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x10 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_4X4_INTER_CB_ENABLE)
2750 | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x20 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_4X4_INTER_CR_ENABLE)
2751 | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x40 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_8X8_INTRA_LUMA_ENABLE)
2752 | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x80 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_8X8_INTER_LUMA_ENABLE);
2753
2754 psMtxEncContext->ui32H264CompControl |=
2755 F_ENCODE(ctx->bEnableLossless ? 1 : 0, INTEL_H264_LL)
2756 | F_ENCODE(ctx->bLossless8x8Prefilter ? 1 : 0, INTEL_H264_LL8X8P);
2757
2758 psMtxEncContext->ui32H264CompIntraPredModes = 0x3ffff;// leave at default for now.
2759 psMtxEncContext->ui32PredCombControl = ctx->ui32PredCombControl;
2760 psMtxEncContext->ui32SkipCodedInterIntra = F_ENCODE(ctx->ui8InterIntraIndex, TOPAZHP_CR_INTER_INTRA_SCALE_IDX)
2761 |F_ENCODE(ctx->ui8CodedSkippedIndex, TOPAZHP_CR_SKIPPED_CODED_SCALE_IDX);
2762
2763 if (ctx->bEnableInpCtrl) {
2764 psMtxEncContext->ui32MBHostCtrl = F_ENCODE(ctx->bEnableHostQP, TOPAZHP_CR_MB_HOST_QP)
2765 |F_ENCODE(ctx->bEnableHostBias, TOPAZHP_CR_MB_HOST_SKIPPED_CODED_SCALE)
2766 |F_ENCODE(ctx->bEnableHostBias, TOPAZHP_CR_MB_HOST_INTER_INTRA_SCALE);
2767 psMtxEncContext->ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTER_INTRA_SCALE_ENABLE)
2768 |F_ENCODE(1, TOPAZHP_CR_SKIPPED_CODED_SCALE_ENABLE);
2769 }
2770
2771 if (ctx->bEnableCumulativeBiases)
2772 psMtxEncContext->ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_CUMULATIVE_BIASES_ENABLE);
2773
2774 psMtxEncContext->ui32PredCombControl |=
2775 F_ENCODE((((ctx->ui8InterIntraIndex == 3) && (ctx->ui8CodedSkippedIndex == 3)) ? 0 : 1), TOPAZHP_CR_INTER_INTRA_SCALE_ENABLE) |
2776 F_ENCODE((ctx->ui8CodedSkippedIndex == 3 ? 0 : 1), TOPAZHP_CR_SKIPPED_CODED_SCALE_ENABLE);
2777 // workaround for BRN 33252, if the Skip coded scale is set then we also have to set the inter/inter enable. We set it enabled and rely on the default value of 3 (unbiased) to keep things behaving.
2778 // psMtxEncContext->ui32PredCombControl |= F_ENCODE((ctx->ui8InterIntraIndex==3?0:1), TOPAZHP_CR_INTER_INTRA_SCALE_ENABLE) | F_ENCODE((ctx->ui8CodedSkippedIndex==3?0:1), TOPAZHP_CR_SKIPPED_CODED_SCALE_ENABLE);
2779 //psMtxEncContext->ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTER_INTRA_SCALE_ENABLE) | F_ENCODE(1, TOPAZHP_CR_SKIPPED_CODED_SCALE_ENABLE);
2780 psMtxEncContext->ui32DeblockCtrl = F_ENCODE(ctx->ui8DeblockIDC, TOPAZ_DB_CR_DISABLE_DEBLOCK_IDC);
2781 psMtxEncContext->ui32VLCControl = 0;
2782
2783 switch (ctx->eStandard) {
2784 case IMG_STANDARD_H264:
2785 psMtxEncContext->ui32VLCControl |= F_ENCODE(1, TOPAZ_VLC_CR_CODEC); // 1 for H.264 note this is inconsistant with the sequencer value
2786 psMtxEncContext->ui32VLCControl |= F_ENCODE(0, TOPAZ_VLC_CR_CODEC_EXTEND);
2787
2788 break;
2789 case IMG_STANDARD_H263:
2790 psMtxEncContext->ui32VLCControl |= F_ENCODE(3, TOPAZ_VLC_CR_CODEC); // 3 for H.263 note this is inconsistant with the sequencer value
2791 psMtxEncContext->ui32VLCControl |= F_ENCODE(0, TOPAZ_VLC_CR_CODEC_EXTEND);
2792
2793 break;
2794 case IMG_STANDARD_MPEG4:
2795 psMtxEncContext->ui32VLCControl |= F_ENCODE(2, TOPAZ_VLC_CR_CODEC); // 2 for Mpeg4 note this is inconsistant with the sequencer value
2796 psMtxEncContext->ui32VLCControl |= F_ENCODE(0, TOPAZ_VLC_CR_CODEC_EXTEND);
2797 break;
2798 case IMG_STANDARD_MPEG2:
2799 psMtxEncContext->ui32VLCControl |= F_ENCODE(0, TOPAZ_VLC_CR_CODEC);
2800 psMtxEncContext->ui32VLCControl |= F_ENCODE(1, TOPAZ_VLC_CR_CODEC_EXTEND);
2801 break;
2802 default:
2803 break;
2804 }
2805
2806 if (ctx->bCabacEnabled) {
2807 psMtxEncContext->ui32VLCControl |= F_ENCODE(1, TOPAZ_VLC_CR_CABAC_ENABLE); // 2 for Mpeg4 note this is inconsistant with the sequencer value
2808 }
2809
2810 psMtxEncContext->ui32VLCControl |= F_ENCODE(ctx->bIsInterlaced ? 1 : 0, TOPAZ_VLC_CR_VLC_FIELD_CODED);
2811 psMtxEncContext->ui32VLCControl |= F_ENCODE(ctx->bH2648x8Transform ? 1 : 0, TOPAZ_VLC_CR_VLC_8X8_TRANSFORM);
2812 psMtxEncContext->ui32VLCControl |= F_ENCODE(ctx->bH264IntraConstrained ? 1 : 0, TOPAZ_VLC_CR_VLC_CONSTRAINED_INTRA);
2813
2814 psMtxEncContext->ui32VLCSliceControl = F_ENCODE(ctx->sRCParams.ui32SliceByteLimit, TOPAZ_VLC_CR_SLICE_SIZE_LIMIT);
2815 psMtxEncContext->ui32VLCSliceMBControl = F_ENCODE(ctx->sRCParams.ui32SliceMBLimit, TOPAZ_VLC_CR_SLICE_MBS_LIMIT);
2816
2817 switch (ctx->eStandard) {
2818 case IMG_STANDARD_H264: {
2819 IMG_UINT32 ui32VertMVLimit = 255; // default to no clipping
2820 if (ctx->ui32VertMVLimit)
2821 ui32VertMVLimit = ctx->ui32VertMVLimit;
2822 // as topaz can only cope with at most 255 (in the register field)
2823 ui32VertMVLimit = tng__min(255,ui32VertMVLimit);
2824 // workaround for BRN 29973 and 30032
2825 {
2826 #if defined(BRN_29973) || defined(BRN_30032)
2827 if (ctx->ui32CoreRev <= 0x30006) {
2828 if ((ctx->ui16Width / 16) & 1) // BRN 30032, if odd number of macroblocks we need to limit vector to +-112
2829 psMtxEncContext->ui32IPEVectorClipping = F_ENCODE(1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_ENABLED)
2830 |F_ENCODE(112, TOPAZHP_CR_IPE_VECTOR_CLIPPING_X)
2831 |F_ENCODE(ui32VertMVLimit, TOPAZHP_CR_IPE_VECTOR_CLIPPING_Y);
2832 else // for 29973 we need to limit vector to +-120
2833 if (ctx->ui16Width >= 1920)
2834 psMtxEncContext->ui32IPEVectorClipping = F_ENCODE(1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_ENABLED)
2835 |F_ENCODE(120, TOPAZHP_CR_IPE_VECTOR_CLIPPING_X)
2836 |F_ENCODE(ui32VertMVLimit, TOPAZHP_CR_IPE_VECTOR_CLIPPING_Y);
2837 else
2838 psMtxEncContext->ui32IPEVectorClipping = F_ENCODE(1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_ENABLED)
2839 |F_ENCODE(255, TOPAZHP_CR_IPE_VECTOR_CLIPPING_X)
2840 |F_ENCODE(ui32VertMVLimit, TOPAZHP_CR_IPE_VECTOR_CLIPPING_Y);
2841 } else
2842 #endif
2843 {
2844 psMtxEncContext->ui32IPEVectorClipping =
2845 F_ENCODE(1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_ENABLED) |
2846 F_ENCODE(255, TOPAZHP_CR_IPE_VECTOR_CLIPPING_X) |
2847 F_ENCODE(ui32VertMVLimit, TOPAZHP_CR_IPE_VECTOR_CLIPPING_Y);
2848 }
2849 }
2850 psMtxEncContext->ui32SPEMvdClipRange = F_ENCODE(0, TOPAZHP_CR_SPE_MVD_CLIP_ENABLE);
2851 }
2852 break;
2853 case IMG_STANDARD_H263:
2854 {
2855 psMtxEncContext->ui32IPEVectorClipping = F_ENCODE(1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_ENABLED)
2856 | F_ENCODE(16 - 1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_X)
2857 | F_ENCODE(16 - 1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_Y);
2858
2859 psMtxEncContext->ui32SPEMvdClipRange = F_ENCODE(1, TOPAZHP_CR_SPE_MVD_CLIP_ENABLE)
2860 | F_ENCODE( 62, TOPAZHP_CR_SPE_MVD_POS_CLIP)
2861 | F_ENCODE((uint32_t)(-64), TOPAZHP_CR_SPE_MVD_NEG_CLIP);
2862 }
2863 break;
2864 case IMG_STANDARD_MPEG4:
2865 case IMG_STANDARD_MPEG2:
2866 {
2867 IMG_UINT8 uX, uY, uResidualSize;
2868 //The maximum MPEG4 and MPEG2 motion vector differential in 1/2 pixels is
2869 //calculated as 1 << (fcode - 1) * 32 or *16 in MPEG2
2870
2871 uResidualSize=(ctx->eStandard == IMG_STANDARD_MPEG4 ? 32 : 16);
2872
2873 uX = tng__min(128 - 1, (((1<<(ctx->sBiasTables.ui32FCode - 1)) * uResidualSize)/4) - 1);
2874 uY = tng__min(104 - 1, (((1<<(ctx->sBiasTables.ui32FCode - 1)) * uResidualSize)/4) - 1);
2875
2876 //Write to register
2877 psMtxEncContext->ui32IPEVectorClipping = F_ENCODE(1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_ENABLED)
2878 | F_ENCODE(uX, TOPAZHP_CR_IPE_VECTOR_CLIPPING_X)
2879 | F_ENCODE(uY, TOPAZHP_CR_IPE_VECTOR_CLIPPING_Y);
2880
2881 psMtxEncContext->ui32SPEMvdClipRange = F_ENCODE(0, TOPAZHP_CR_SPE_MVD_CLIP_ENABLE);
2882 }
2883 break;
2884 case IMG_STANDARD_JPEG:
2885 case IMG_STANDARD_NONE:
2886 default:
2887 break;
2888 }
2889 #ifdef FIRMWARE_BIAS
2890 //copy the bias tables
2891 {
2892 int n;
2893 for (n = 52; n >= 0; n -= 2) {
2894 psMtxEncContext->aui32DirectBias_P[n >> 1] = ctx->sBiasTables.aui32DirectBias_P[n];
2895 psMtxEncContext->aui32InterBias_P[n >> 1] = ctx->sBiasTables.aui32InterBias_P[n];
2896 psMtxEncContext->aui32DirectBias_B[n >> 1] = ctx->sBiasTables.aui32DirectBias_B[n];
2897 psMtxEncContext->aui32InterBias_B[n >> 1] = ctx->sBiasTables.aui32InterBias_B[n];
2898 }
2899 }
2900 #endif
2901
2902 //copy the scale-tables
2903 tng__generate_scale_tables(psMtxEncContext);
2904 // memcpy(psMtxEncContext->ui32InterIntraScale, ctx->ui32InterIntraScale, sizeof(IMG_UINT32)*SCALE_TBL_SZ);
2905 // memcpy(psMtxEncContext->ui32SkippedCodedScale, ctx->ui32SkippedCodedScale, sizeof(IMG_UINT32)*SCALE_TBL_SZ);
2906
2907 // WEIGHTED PREDICTION
2908 psMtxEncContext->b8WeightedPredictionEnabled = ctx->bWeightedPrediction;
2909 psMtxEncContext->ui8MTXWeightedImplicitBiPred = ctx->ui8VPWeightedImplicitBiPred;
2910
2911 // SEI_INSERTION
2912 psMtxEncContext->b8InsertHRDparams = ctx->bInsertHRDParams;
2913 if (psMtxEncContext->b8InsertHRDparams & !ctx->sRCParams.ui32BitsPerSecond) { //ctx->uBitRate
2914 /* HRD parameters are meaningless without a bitrate */
2915 psMtxEncContext->b8InsertHRDparams = IMG_FALSE;
2916 }
2917 if (psMtxEncContext->b8InsertHRDparams) {
2918 psMtxEncContext->ui64ClockDivBitrate = (90000 * 0x100000000LL);
2919 psMtxEncContext->ui64ClockDivBitrate /= ctx->sRCParams.ui32BitsPerSecond; //ctx->uBitRate;
2920 psMtxEncContext->ui32MaxBufferMultClockDivBitrate = (IMG_UINT32)(((IMG_UINT64)(ctx->sRCParams.ui32BufferSize) *
2921 (IMG_UINT64) 90000) / (IMG_UINT64) ctx->sRCParams.ui32BitsPerSecond);
2922 }
2923
2924 memcpy(&psMtxEncContext->sInParams, &ctx->sPicParams.sInParams, sizeof(IN_RC_PARAMS));
2925 // Update MV Scaling settings
2926 // IDR
2927 // memcpy(&psMtxEncContext->sMVSettingsIdr, &ctx->sMVSettingsIdr, sizeof(IMG_MV_SETTINGS));
2928 // NonB (I or P)
2929 // for (i = 0; i <= MAX_BFRAMES; i++)
2930 // memcpy(&psMtxEncContext->sMVSettingsNonB[i], &ctx->sMVSettingsNonB[i], sizeof(IMG_MV_SETTINGS));
2931
2932 psMtxEncContext->ui32LRITC_Cache_Chunk_Config =
2933 F_ENCODE(ctx->uChunksPerMb, INTEL_CH_PM) |
2934 F_ENCODE(ctx->uMaxChunks, INTEL_CH_MX) |
2935 F_ENCODE(ctx->uMaxChunks - ctx->uPriorityChunks, INTEL_CH_PY);
2936
2937
2938 //they would be set in function tng__prepare_templates()
2939 psMtxEncContext->ui32FirstPicFlags = ctx->ui32FirstPicFlags;
2940 psMtxEncContext->ui32NonFirstPicFlags = ctx->ui32NonFirstPicFlags;
2941
2942 #ifdef LTREFHEADER
2943 psMtxEncContext->i8SliceHeaderSlotNum = -1;
2944 #endif
2945
2946 {
2947 memset(psMtxEncContext->aui8PicOnLevel, 0, sizeof(psMtxEncContext->aui8PicOnLevel));
2948 psb_buffer_map(&(ps_mem->bufs_flat_gop), &(ps_mem->bufs_flat_gop.virtual_addr));
2949 if (ps_mem->bufs_flat_gop.virtual_addr == NULL) {
2950 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping flat gop\n", __FUNCTION__);
2951 return ;
2952 }
2953 tng__minigop_generate_flat(ps_mem->bufs_flat_gop.virtual_addr, psMtxEncContext->ui32BFrameCount,
2954 psMtxEncContext->ui8RefSpacing, psMtxEncContext->aui8PicOnLevel);
2955 psb_buffer_unmap(&(ps_mem->bufs_flat_gop));
2956
2957 if (ctx->sRCParams.b16Hierarchical) {
2958 memset(psMtxEncContext->aui8PicOnLevel, 0, sizeof(psMtxEncContext->aui8PicOnLevel));
2959 psb_buffer_map(&(ps_mem->bufs_hierar_gop), &(ps_mem->bufs_hierar_gop.virtual_addr));
2960 if (ps_mem->bufs_hierar_gop.virtual_addr == NULL) {
2961 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping sei header\n", __FUNCTION__);
2962 return ;
2963 }
2964 tng_minigop_generate_hierarchical(ps_mem->bufs_hierar_gop.virtual_addr, psMtxEncContext->ui32BFrameCount,
2965 psMtxEncContext->ui8RefSpacing, psMtxEncContext->aui8PicOnLevel);
2966 psb_buffer_unmap(&(ps_mem->bufs_hierar_gop));
2967 }
2968 }
2969
2970 #if INPUT_SCALER_SUPPORTED
2971 if (ctx->bEnableScaler) {
2972 IMG_UINT8 sccCoeffs[4][16];
2973 IMG_UINT32 ui32PitchX, ui32PitchY;
2974 IMG_INT32 i32Phase, i32Tap;
2975
2976 ui32PitchX = (((IMG_UINT32)(psVideoParams->ui16SourceWidth - psVideoParams->ui8CropLeft - psVideoParams->ui8CropRight)) << 12) / psVideoParams->ui16Width;
2977 ui32PitchY = (((IMG_UINT32)(psVideoParams->ui16SourceFrameHeight - psVideoParams->ui8CropTop - psVideoParams->ui8CropBottom)) << 12) / psVideoParams->ui16FrameHeight;
2978
2979 // Input size
2980 psMtxEncContext->ui32ScalerInputSizeReg = F_ENCODE(psVideoParams->ui16SourceWidth - 1, TOPAZHP_EXT_CR_SCALER_INPUT_WIDTH_MIN1) |
2981 F_ENCODE((psVideoParams->ui16SourceFrameHeight >> (psVideo->bIsInterlaced ? 1 : 0)) - 1, TOPAZHP_EXT_CR_SCALER_INPUT_HEIGHT_MIN1);
2982
2983 psMtxEncContext->ui32ScalerCropReg = F_ENCODE(psVideoParams->ui8CropLeft, TOPAZHP_EXT_CR_SCALER_INPUT_CROP_HOR) |
2984 F_ENCODE(psVideoParams->ui8CropTop, TOPAZHP_EXT_CR_SCALER_INPUT_CROP_VER);
2985
2986 // Scale factors
2987 psMtxEncContext->ui32ScalerPitchReg = 0;
2988
2989 if (ui32PitchX > 0x3FFF) {
2990 psMtxEncContext->ui32ScalerPitchReg |= F_ENCODE(1, TOPAZHP_EXT_CR_SCALER_HOR_BILINEAR_FILTER);
2991 ui32PitchX >>= 1;
2992 }
2993
2994 if (ui32PitchX > 0x3FFF) {
2995 ui32PitchX = 0x3FFF;
2996 }
2997
2998 if (ui32PitchY > 0x3FFF) {
2999 psMtxEncContext->ui32ScalerPitchReg |= F_ENCODE(1, TOPAZHP_EXT_CR_SCALER_VER_BILINEAR_FILTER);
3000 ui32PitchY >>= 1;
3001 }
3002
3003 if (ui32PitchY > 0x3FFF) {
3004 ui32PitchY = 0x3FFF;
3005 }
3006
3007 psMtxEncContext->ui32ScalerPitchReg |= F_ENCODE(ui32PitchX, TOPAZHP_EXT_CR_SCALER_INPUT_HOR_PITCH) |
3008 F_ENCODE(ui32PitchY, TOPAZHP_EXT_CR_SCALER_INPUT_VER_PITCH);
3009
3010
3011 // Coefficients
3012 VIDEO_CalcCoefs_FromPitch(((IMG_FLOAT)ui32PitchX) / 4096.0f, sccCoeffs);
3013
3014 for (i32Phase = 0; i32Phase < 4; i32Phase++) {
3015 psMtxEncContext->asHorScalerCoeffRegs[i32Phase] = 0;
3016 for (i32Tap = 0; i32Tap < 4; i32Tap++) {
3017 psMtxEncContext->asHorScalerCoeffRegs[i32Phase] |= F_ENCODE(sccCoeffs[3 - i32Tap][(i32Phase * 2) + 1], TOPAZHP_EXT_CR_SCALER_HOR_LUMA_COEFF(i32Tap));
3018 }
3019 }
3020
3021 VIDEO_CalcCoefs_FromPitch(((IMG_FLOAT)ui32PitchY) / 4096.0f, sccCoeffs);
3022
3023 for (i32Phase = 0; i32Phase < 4; i32Phase++) {
3024 psMtxEncContext->asVerScalerCoeffRegs[i32Phase] = 0;
3025 for (i32Tap = 0; i32Tap < 4; i32Tap++) {
3026 psMtxEncContext->asVerScalerCoeffRegs[i32Phase] |= F_ENCODE(sccCoeffs[3 - i32Tap][(i32Phase * 2) + 1], TOPAZHP_EXT_CR_SCALER_VER_LUMA_COEFF(i32Tap));
3027 }
3028 }
3029 } else {
3030 // Disable scaling
3031 psMtxEncContext->ui32ScalerInputSizeReg = 0;
3032 }
3033 #endif // INPUT_SCALER_SUPPORTED
3034
3035 psb_buffer_unmap(&(ps_mem->bufs_mtx_context));
3036
3037 return ;
3038 }
3039
tng__setvideo_cmdbuf(context_ENC_p ctx,IMG_UINT32 ui32StreamIndex)3040 static void tng__setvideo_cmdbuf(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
3041 {
3042 context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
3043 context_ENC_mem_size *ps_mem_size = &(ctx->ctx_mem_size);
3044 #ifndef _TNG_FRAMES_
3045 context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
3046 #endif
3047 IMG_MTX_VIDEO_CONTEXT* psMtxEncContext = NULL;
3048 IMG_INT32 i;
3049
3050 psb_buffer_map(&(ps_mem->bufs_mtx_context), &(ps_mem->bufs_mtx_context.virtual_addr));
3051 if (ps_mem->bufs_mtx_context.virtual_addr == NULL) {
3052 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping sei header\n", __FUNCTION__);
3053 return ;
3054 }
3055 psMtxEncContext = (IMG_MTX_VIDEO_CONTEXT*)(ps_mem->bufs_mtx_context.virtual_addr);
3056
3057 tng_cmdbuf_set_phys(&(psMtxEncContext->ui32MVSettingsBTable), 0,
3058 &(ps_mem->bufs_mv_setting_btable), 0, 0);
3059 if (ctx->sRCParams.b16Hierarchical)
3060 tng_cmdbuf_set_phys(&psMtxEncContext->ui32MVSettingsHierarchical, 0,
3061 &(ps_mem->bufs_mv_setting_hierar), 0, 0);
3062 #ifdef _TNG_FRAMES_
3063 tng_cmdbuf_set_phys(psMtxEncContext->apReconstructured, ctx->i32PicNodes,
3064 &(ps_mem->bufs_recon_pictures), 0, ps_mem_size->recon_pictures);
3065 #else
3066 for (i = 0; i < ctx->i32PicNodes; i++) {
3067 tng_cmdbuf_set_phys(&(psMtxEncContext->apReconstructured[i]), 0,
3068 &(ps_buf->ref_surface[i]->psb_surface->buf), 0, 0);
3069 }
3070 #endif
3071
3072 tng_cmdbuf_set_phys(psMtxEncContext->apColocated, ctx->i32PicNodes,
3073 &(ps_mem->bufs_colocated), 0, ps_mem_size->colocated);
3074
3075 tng_cmdbuf_set_phys(psMtxEncContext->apMV, ctx->i32MVStores,
3076 &(ps_mem->bufs_mv), 0, ps_mem_size->mv);
3077
3078 if (ctx->bEnableMVC) {
3079 tng_cmdbuf_set_phys(psMtxEncContext->apInterViewMV, 2,
3080 &(ps_mem->bufs_interview_mv), 0, ps_mem_size->interview_mv);
3081 }
3082
3083 tng_cmdbuf_set_phys(psMtxEncContext->apWritebackRegions, WB_FIFO_SIZE,
3084 &(ctx->bufs_writeback), 0, ps_mem_size->writeback);
3085
3086 tng_cmdbuf_set_phys(psMtxEncContext->apAboveParams, (IMG_UINT32)(ctx->ui8PipesToUse),
3087 &(ps_mem->bufs_above_params), 0, ps_mem_size->above_params);
3088
3089 // SEI_INSERTION
3090 if (ctx->bInsertHRDParams) {
3091 tng_cmdbuf_set_phys(&psMtxEncContext->pSEIBufferingPeriodTemplate, 0,
3092 &(ps_mem->bufs_sei_header), ps_mem_size->sei_header, ps_mem_size->sei_header);
3093 tng_cmdbuf_set_phys(&psMtxEncContext->pSEIPictureTimingTemplate, 0,
3094 &(ps_mem->bufs_sei_header), ps_mem_size->sei_header * 2, ps_mem_size->sei_header);
3095 }
3096
3097 tng_cmdbuf_set_phys(psMtxEncContext->apSliceParamsTemplates, NUM_SLICE_TYPES,
3098 &(ps_mem->bufs_slice_template), 0, ps_mem_size->slice_template);
3099
3100 tng_cmdbuf_set_phys(psMtxEncContext->aui32SliceMap, ctx->ui8SlotsInUse,
3101 &(ps_mem->bufs_slice_map), 0, ps_mem_size->slice_map);
3102
3103 // WEIGHTED PREDICTION
3104 if (ctx->bWeightedPrediction || (ctx->ui8VPWeightedImplicitBiPred == WBI_EXPLICIT)) {
3105 tng_cmdbuf_set_phys(psMtxEncContext->aui32WeightedPredictionVirtAddr, ctx->ui8SlotsInUse,
3106 &(ps_mem->bufs_weighted_prediction), 0, ps_mem_size->weighted_prediction);
3107 }
3108
3109 tng_cmdbuf_set_phys(&psMtxEncContext->ui32FlatGopStruct, 0, &(ps_mem->bufs_flat_gop), 0, 0);
3110 if (psMtxEncContext->b8Hierarchical)
3111 tng_cmdbuf_set_phys(&psMtxEncContext->ui32HierarGopStruct, 0, &(ps_mem->bufs_hierar_gop), 0, 0);
3112
3113 #ifdef LTREFHEADER
3114 tng_cmdbuf_set_phys(psMtxEncContext->aui32LTRefHeader, ctx->ui8SlotsInUse,
3115 &(ps_mem->bufs_lt_ref_header), 0, ps_mem_size->lt_ref_header);
3116 #endif
3117
3118 tng_cmdbuf_set_phys(psMtxEncContext->apPicHdrTemplates, 4,
3119 &(ps_mem->bufs_pic_template), 0, ps_mem_size->pic_template);
3120
3121 if (ctx->eStandard == IMG_STANDARD_H264) {
3122 tng_cmdbuf_set_phys(&(psMtxEncContext->apSeqHeader), 0,
3123 &(ps_mem->bufs_seq_header), 0, ps_mem_size->seq_header);
3124 if (ctx->bEnableMVC)
3125 tng_cmdbuf_set_phys(&(psMtxEncContext->apSubSetSeqHeader), 0,
3126 &(ps_mem->bufs_sub_seq_header), 0, ps_mem_size->seq_header);
3127 }
3128
3129 if (ctx->ui8EnableSelStatsFlags & ESF_FIRST_STAGE_STATS) {
3130 tng_cmdbuf_set_phys(psMtxEncContext->pFirstPassOutParamAddr, ctx->ui8SlotsInUse,
3131 &(ps_mem->bufs_first_pass_out_params), 0, ps_mem_size->first_pass_out_params);
3132 }
3133
3134 #ifndef EXCLUDE_BEST_MP_DECISION_DATA
3135 // Store the feedback memory address for all "5" slots in the context
3136 if (ctx->ui8EnableSelStatsFlags & ESF_MP_BEST_MB_DECISION_STATS
3137 || ctx->ui8EnableSelStatsFlags & ESF_MP_BEST_MOTION_VECTOR_STATS) {
3138 tng_cmdbuf_set_phys(psMtxEncContext->pFirstPassOutBestMultipassParamAddr, ctx->ui8SlotsInUse,
3139 &(ps_mem->bufs_first_pass_out_best_multipass_param), 0, ps_mem_size->first_pass_out_best_multipass_param);
3140 }
3141 #endif
3142
3143 //Store the MB-Input control parameter memory for all the 5-slots in the context
3144 if (ctx->bEnableInpCtrl) {
3145 tng_cmdbuf_set_phys(psMtxEncContext->pMBCtrlInParamsAddr, ctx->ui8SlotsInUse,
3146 &(ps_mem->bufs_mb_ctrl_in_params), 0, ps_mem_size->mb_ctrl_in_params);
3147 }
3148
3149 psb_buffer_unmap(&(ps_mem->bufs_mtx_context));
3150
3151 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s end\n", __FUNCTION__);
3152
3153 return ;
3154 }
3155
tng__validate_params(context_ENC_p ctx)3156 static VAStatus tng__validate_params(context_ENC_p ctx)
3157 {
3158 VAStatus vaStatus = VA_STATUS_SUCCESS;
3159 IMG_UINT16 ui16WidthInMbs = (ctx->ui16Width + 15) >> 4;
3160 IMG_UINT16 ui16PictureHeight = ((ctx->ui16FrameHeight >> (ctx->bIsInterlaced ? 1 : 0)) + 15) & ~15;
3161 IMG_UINT16 ui16FrameHeightInMbs = (ctx->ui16FrameHeight + 15) >> 4;
3162
3163 if ((ctx->ui16Width & 0xf) != 0) {
3164 return VA_STATUS_ERROR_INVALID_PARAMETER;
3165 }
3166
3167 if ((ctx->ui16FrameHeight & 0xf) != 0) {
3168 return VA_STATUS_ERROR_INVALID_PARAMETER;
3169 }
3170
3171 ctx->uMBspS = ui16WidthInMbs * ui16FrameHeightInMbs * ctx->sRCParams.ui32FrameRate;
3172
3173 if (ctx->ui32CoreRev >= MIN_36_REV) {
3174 if ((ctx->ui16Width > 4096) || (ctx->ui16PictureHeight > 4096)) {
3175 return VA_STATUS_ERROR_INVALID_PARAMETER;
3176 }
3177 if ((ui16WidthInMbs << 4) * ui16PictureHeight > 2048 * 2048) {
3178 return VA_STATUS_ERROR_INVALID_PARAMETER;
3179 }
3180 } else {
3181 if ((ctx->ui16Width > 2048) || (ui16PictureHeight > 2048)) {
3182 return VA_STATUS_ERROR_INVALID_PARAMETER;
3183 }
3184 }
3185
3186 if (ctx->eStandard == IMG_STANDARD_H264) {
3187 if ((ctx->ui8DeblockIDC == 0) && (ctx->bArbitrarySO))
3188 ctx->ui8DeblockIDC = 2;
3189
3190 if ((ctx->ui8DeblockIDC == 0) && ((IMG_UINT32)(ctx->ui8PipesToUse) > 1) && (ctx->ui8SlicesPerPicture > 1)) {
3191 drv_debug_msg(VIDEO_DEBUG_GENERAL, "WARNING: Full deblocking with multiple pipes will cause a mismatch between reconstructed and encoded video\n");
3192 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Consider using -deblockIDC 2 or -deblockIDC 1 instead if matching reconstructed video is required.\n");
3193 drv_debug_msg(VIDEO_DEBUG_GENERAL, "WARNING: Forcing -deblockIDC = 2 for HW verification.\n");
3194 ctx->ui8DeblockIDC = 2;
3195 }
3196 } else if (ctx->eStandard == IMG_STANDARD_H263) {
3197 ctx->bArbitrarySO = IMG_FALSE;
3198 ctx->ui8DeblockIDC = 1;
3199 } else {
3200 ctx->ui8DeblockIDC = 1;
3201 }
3202
3203 //ctx->sRCParams.ui32SliceByteLimit = 0;
3204 ctx->sRCParams.ui32SliceMBLimit = 0;
3205 //slice params
3206 if (ctx->ui8SlicesPerPicture == 0)
3207 ctx->ui8SlicesPerPicture = ctx->sCapsParams.ui16RecommendedSlices;
3208 else {
3209 if (ctx->ui8SlicesPerPicture > ctx->sCapsParams.ui16MaxSlices)
3210 ctx->ui8SlicesPerPicture = ctx->sCapsParams.ui16MaxSlices;
3211 else if (ctx->ui8SlicesPerPicture < ctx->sCapsParams.ui16MinSlices)
3212 ctx->ui8SlicesPerPicture = ctx->sCapsParams.ui16MinSlices;
3213 }
3214
3215 if (ctx->ui32pseudo_rand_seed == UNINIT_PARAM) {
3216 // When -randseed is uninitialised, initialise seed using other commandline values
3217 ctx->ui32pseudo_rand_seed = (IMG_UINT32) ((ctx->sRCParams.ui32InitialQp +
3218 ctx->ui16PictureHeight + ctx->ui16Width + ctx->sRCParams.ui32BitsPerSecond) & 0xffffffff);
3219 // iQP_Luma + pParams->uHeight + pParams->uWidth + pParams->uBitRate) & 0xffffffff);
3220 }
3221
3222 if (ctx->eStandard == IMG_STANDARD_H264) {
3223 ctx->ui8PipesToUse = tng__min(ctx->ui8PipesToUse, ctx->ui8SlicesPerPicture);
3224 } else {
3225 ctx->ui8PipesToUse = 1;
3226 }
3227
3228 return vaStatus;
3229 }
3230
tng__validate_busize(context_ENC_p ctx)3231 static VAStatus tng__validate_busize(context_ENC_p ctx)
3232 {
3233 //IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
3234 // if no BU size is given then pick one ourselves, if doing arbitrary slice order then make BU = width in bu's
3235 // forces slice boundaries to no be mid-row
3236 if (ctx->bArbitrarySO || (ctx->ui32BasicUnit == 0)) {
3237 ctx->ui32BasicUnit = (ctx->ui16Width / 16);
3238 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Patched Basic unit to %d\n", ctx->ui32BasicUnit);
3239 } else {
3240 IMG_UINT32 ui32MBs, ui32MBsperSlice, ui32MBsLastSlice;
3241 IMG_UINT32 ui32BUs;
3242 IMG_INT32 i32SliceHeight;
3243 IMG_UINT32 ui32MaxSlicesPerPipe, ui32MaxMBsPerPipe, ui32MaxBUsPerPipe;
3244
3245 ui32MBs = ctx->ui16PictureHeight * ctx->ui16Width / (16 * 16);
3246
3247 i32SliceHeight = ctx->ui16PictureHeight / ctx->ui8SlicesPerPicture;
3248 i32SliceHeight &= ~15;
3249
3250 ui32MBsperSlice = (i32SliceHeight * ctx->ui16Width) / (16 * 16);
3251 ui32MBsLastSlice = ui32MBs - (ui32MBsperSlice * (ctx->ui8SlicesPerPicture - 1));
3252
3253 // they have given us a basic unit so validate it
3254 if (ctx->ui32BasicUnit < 6) {
3255 drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nERROR: Basic unit size too small, must be greater than 6\n");
3256 return VA_STATUS_ERROR_UNKNOWN;
3257 }
3258
3259 if (ctx->ui32BasicUnit > ui32MBsperSlice) {
3260 drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nERROR: Basic unit size(%d) too large", ctx->ui32BasicUnit);
3261 drv_debug_msg(VIDEO_DEBUG_GENERAL, " must not be greater than the number of macroblocks in a slice (%d)\n", ui32MBsperSlice);
3262 return VA_STATUS_ERROR_UNKNOWN;
3263 }
3264 if (ctx->ui32BasicUnit > ui32MBsLastSlice) {
3265 drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nERROR: Basic unit size(%d) too large", ctx->ui32BasicUnit);
3266 drv_debug_msg(VIDEO_DEBUG_GENERAL, " must not be greater than the number of macroblocks in a slice (%d)\n", ui32MBsLastSlice);
3267 return VA_STATUS_ERROR_UNKNOWN;
3268 }
3269
3270 ui32BUs = ui32MBsperSlice / ctx->ui32BasicUnit;
3271 if ((ui32BUs * ctx->ui32BasicUnit) != ui32MBsperSlice) {
3272 drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nERROR: Basic unit size(%d) not an integer divisor of MB's in a slice(%d)",
3273 ctx->ui32BasicUnit, ui32MBsperSlice);
3274 return VA_STATUS_ERROR_UNKNOWN;
3275 }
3276
3277 ui32BUs = ui32MBsLastSlice / ctx->ui32BasicUnit;
3278 if ((ui32BUs * ctx->ui32BasicUnit) != ui32MBsLastSlice) {
3279 drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nERROR: Basic unit size(%d) not an integer divisor of MB's in the last slice(%d)",
3280 ctx->ui32BasicUnit, ui32MBsLastSlice);
3281 return VA_STATUS_ERROR_UNKNOWN;
3282 }
3283
3284 // check if the number of BUs per pipe is greater than 200
3285 ui32MaxSlicesPerPipe = (IMG_UINT32)(ctx->ui8SlicesPerPicture + ctx->ui8PipesToUse - 1) / (IMG_UINT32)(ctx->ui8PipesToUse);
3286 ui32MaxMBsPerPipe = (ui32MBsperSlice * (ui32MaxSlicesPerPipe - 1)) + ui32MBsLastSlice;
3287 ui32MaxBUsPerPipe = (ui32MaxMBsPerPipe + ctx->ui32BasicUnit - 1) / ctx->ui32BasicUnit;
3288 if (ui32MaxBUsPerPipe > 200) {
3289 drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nERROR: Basic unit size too small. There must be less than 201 basic units per slice");
3290 return VA_STATUS_ERROR_UNKNOWN;
3291 }
3292 }
3293
3294 ctx->sRCParams.ui32BUSize = ctx->ui32BasicUnit;
3295 return VA_STATUS_SUCCESS;
3296 }
3297
tng__cmdbuf_new_codec(context_ENC_p ctx)3298 static VAStatus tng__cmdbuf_new_codec(context_ENC_p ctx)
3299 {
3300 VAStatus vaStatus = VA_STATUS_SUCCESS;
3301 tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
3302 psb_driver_data_p driver_data = ctx->obj_context->driver_data;
3303 context_ENC_mem *ps_mem = &(ctx->ctx_mem[0]);
3304
3305 *cmdbuf->cmd_idx++ =
3306 ((MTX_CMDID_SW_NEW_CODEC & MTX_CMDWORD_ID_MASK) << MTX_CMDWORD_ID_SHIFT) |
3307 ((ctx->eCodec & MTX_CMDWORD_CORE_MASK) << MTX_CMDWORD_CORE_SHIFT) |
3308 (((driver_data->context_id & MTX_CMDWORD_COUNT_MASK) << MTX_CMDWORD_COUNT_SHIFT));
3309 // (((driver_data->drm_context & MTX_CMDWORD_COUNT_MASK) << MTX_CMDWORD_COUNT_SHIFT));
3310
3311 tng_cmdbuf_insert_command_param((ctx->ui16Width << 16) | ctx->ui16PictureHeight);
3312
3313 return vaStatus;
3314 }
3315
tng__cmdbuf_doheader(context_ENC_p ctx)3316 static VAStatus tng__cmdbuf_doheader(context_ENC_p ctx)
3317 {
3318 VAStatus vaStatus = VA_STATUS_SUCCESS;
3319 context_ENC_mem *ps_mem = &(ctx->ctx_mem[ctx->ui32StreamID]);
3320 tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
3321
3322 cmdbuf->cmd_idx_saved[TNG_CMDBUF_PIC_HEADER_IDX] = cmdbuf->cmd_idx;
3323 tng_cmdbuf_insert_command(ctx->obj_context, 0,
3324 MTX_CMDID_DO_HEADER,
3325 0,
3326 &(ps_mem->bufs_seq_header),
3327 0);
3328 return vaStatus;
3329 }
3330
tng__cmdbuf_lowpower(context_ENC_p ctx)3331 static VAStatus tng__cmdbuf_lowpower(context_ENC_p ctx)
3332 {
3333 VAStatus vaStatus = VA_STATUS_SUCCESS;
3334 tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
3335 psb_driver_data_p driver_data = ctx->obj_context->driver_data;
3336
3337 *cmdbuf->cmd_idx++ =
3338 ((MTX_CMDID_SW_LEAVE_LOWPOWER & MTX_CMDWORD_ID_MASK) << MTX_CMDWORD_ID_SHIFT) |
3339 (((ctx->ui32RawFrameCount == 0 ? 1 : 0) & MTX_CMDWORD_CORE_MASK) << MTX_CMDWORD_CORE_SHIFT) |
3340 (((driver_data->context_id & MTX_CMDWORD_COUNT_MASK) << MTX_CMDWORD_COUNT_SHIFT));
3341
3342 tng_cmdbuf_insert_command_param(ctx->eCodec);
3343
3344 return vaStatus;
3345 }
3346
tng__cmdbuf_load_bias(context_ENC_p ctx)3347 static VAStatus tng__cmdbuf_load_bias(context_ENC_p ctx)
3348 {
3349 VAStatus vaStatus = VA_STATUS_SUCCESS;
3350
3351 //init bias parameters
3352 tng_init_bias_params(ctx);
3353
3354 vaStatus = tng__generate_bias(ctx);
3355 if (vaStatus != VA_STATUS_SUCCESS) {
3356 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: generate bias params\n", __FUNCTION__, vaStatus);
3357 }
3358
3359 vaStatus = tng_load_bias(ctx, IMG_INTER_P);
3360 if (vaStatus != VA_STATUS_SUCCESS) {
3361 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: load bias params\n", __FUNCTION__, vaStatus);
3362 }
3363 return vaStatus;
3364 }
3365
tng__cmdbuf_setvideo(context_ENC_p ctx,IMG_UINT32 ui32StreamIndex)3366 static VAStatus tng__cmdbuf_setvideo(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
3367 {
3368 VAStatus vaStatus = VA_STATUS_SUCCESS;
3369 context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
3370
3371 tng__setvideo_params(ctx, ui32StreamIndex);
3372 tng__setvideo_cmdbuf(ctx, ui32StreamIndex);
3373
3374 tng_cmdbuf_insert_command(ctx->obj_context, ctx->ui32StreamID,
3375 MTX_CMDID_SETVIDEO, 0, &(ps_mem->bufs_mtx_context), 0);
3376
3377 return vaStatus;
3378 }
3379
tng__rc_update(context_ENC_p ctx,IMG_UINT32 ui32NewBitrate,IMG_UINT8 ui8NewFrameQP,IMG_UINT8 ui8NewFrameMinQP,IMG_UINT8 ui8NewFrameMaxQP,IMG_UINT16 ui16NewIntraPeriod)3380 static void tng__rc_update(
3381 context_ENC_p ctx,
3382 IMG_UINT32 ui32NewBitrate,
3383 IMG_UINT8 ui8NewFrameQP,
3384 IMG_UINT8 ui8NewFrameMinQP,
3385 IMG_UINT8 ui8NewFrameMaxQP,
3386 IMG_UINT16 ui16NewIntraPeriod)
3387 {
3388 psb_buffer_p buf = (psb_buffer_p)(F_ENCODE(ui8NewFrameMinQP, MTX_MSG_RC_UPDATE_MIN_QP) |
3389 F_ENCODE(ui8NewFrameMaxQP, MTX_MSG_RC_UPDATE_MAX_QP) |
3390 F_ENCODE(ui16NewIntraPeriod, MTX_MSG_RC_UPDATE_INTRA));
3391 tng_cmdbuf_insert_command(
3392 ctx->obj_context,
3393 ctx->ui32StreamID,
3394 MTX_CMDID_RC_UPDATE,
3395 F_ENCODE(ui8NewFrameQP, MTX_MSG_RC_UPDATE_QP) |
3396 F_ENCODE(ui32NewBitrate, MTX_MSG_RC_UPDATE_BITRATE),
3397 buf,
3398 0);
3399 }
3400
tng__update_ratecontrol(context_ENC_p ctx,IMG_UINT32 ui32StreamIndex)3401 static VAStatus tng__update_ratecontrol(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
3402 {
3403 VAStatus vaStatus = VA_STATUS_SUCCESS;
3404 IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
3405 IMG_UINT32 ui32CmdData = 0;
3406 IMG_UINT32 ui32NewBitsPerFrame = 0;
3407 IMG_UINT8 ui8NewVCMIFrameQP = 0;
3408
3409 if (!(ctx->rc_update_flag))
3410 return vaStatus;
3411
3412 tng__setup_rcdata(ctx);
3413
3414 drv_debug_msg(VIDEO_DEBUG_GENERAL,
3415 "%s: frame[%d] bits_per_second = %d, min_qp = %d, max_qp = %d, initial_qp = %d\n",
3416 __FUNCTION__, ctx->ui32FrameCount[ui32StreamIndex], psRCParams->ui32BitsPerSecond,
3417 psRCParams->iMinQP, ctx->max_qp, psRCParams->ui32InitialQp);
3418
3419 if (ctx->rc_update_flag & RC_MASK_frame_rate) {
3420 tng__rc_update(ctx, psRCParams->ui32BitsPerSecond, -1, -1, -1, -1);
3421 ctx->rc_update_flag &= ~RC_MASK_frame_rate;
3422 }
3423
3424 if (ctx->rc_update_flag & RC_MASK_bits_per_second) {
3425 tng__rc_update(ctx, psRCParams->ui32BitsPerSecond, -1, -1, -1, -1);
3426 ctx->rc_update_flag &= ~RC_MASK_bits_per_second;
3427 }
3428
3429 if (ctx->rc_update_flag & RC_MASK_min_qp) {
3430 tng__rc_update(ctx, -1, -1, psRCParams->iMinQP, -1, -1);
3431 ctx->rc_update_flag &= ~RC_MASK_min_qp;
3432 }
3433
3434 if (ctx->rc_update_flag & RC_MASK_max_qp) {
3435 tng__rc_update(ctx, -1, -1, -1, ctx->max_qp, -1);
3436 ctx->rc_update_flag &= ~RC_MASK_max_qp;
3437 }
3438
3439 if (ctx->rc_update_flag & RC_MASK_initial_qp) {
3440 tng__rc_update(ctx, -1, psRCParams->ui32InitialQp, -1, -1, -1);
3441 ctx->rc_update_flag &= ~RC_MASK_initial_qp;
3442 }
3443
3444 if (ctx->rc_update_flag & RC_MASK_intra_period) {
3445 tng__rc_update(ctx, -1, -1, -1, -1, ctx->ui32IntraCnt);
3446 ctx->rc_update_flag &= ~RC_MASK_intra_period;
3447 }
3448
3449 return vaStatus;
3450 }
3451
tng__update_frametype(context_ENC_p ctx,IMG_FRAME_TYPE eFrameType)3452 static VAStatus tng__update_frametype(context_ENC_p ctx, IMG_FRAME_TYPE eFrameType)
3453 {
3454 VAStatus vaStatus = VA_STATUS_SUCCESS;
3455 IMG_UINT32 ui32CmdData = 0;
3456
3457 ui32CmdData = F_ENCODE(IMG_PICMGMT_REF_TYPE, MTX_MSG_PICMGMT_SUBTYPE) |
3458 F_ENCODE(eFrameType, MTX_MSG_PICMGMT_DATA);
3459
3460 tng_cmdbuf_insert_command(ctx->obj_context, ctx->ui32StreamID,
3461 MTX_CMDID_PICMGMT ,
3462 ui32CmdData, 0, 0);
3463
3464 return vaStatus;
3465 }
3466
tng__cmdbuf_send_picmgmt(context_ENC_p ctx,IMG_UINT32 ui32StreamIndex)3467 static VAStatus tng__cmdbuf_send_picmgmt(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
3468 {
3469 VAStatus vaStatus = VA_STATUS_SUCCESS;
3470 IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
3471
3472 if (!(ctx->rc_update_flag))
3473 return vaStatus;
3474
3475 //tng__setup_rcdata(ctx);
3476 drv_debug_msg(VIDEO_DEBUG_GENERAL,
3477 "%s: ui32BitsPerSecond = %d, ui32FrameRate = %d, ui32InitialQp = %d\n",
3478 __FUNCTION__, psRCParams->ui32BitsPerSecond,
3479 psRCParams->ui32FrameRate, psRCParams->ui32InitialQp);
3480 drv_debug_msg(VIDEO_DEBUG_GENERAL,
3481 "%s: frame_count[%d] = %d\n", __FUNCTION__,
3482 ui32StreamIndex, ctx->ui32FrameCount[ui32StreamIndex]);
3483
3484 return vaStatus;
3485 }
3486
3487
tng__cmdbuf_provide_buffer(context_ENC_p ctx,IMG_UINT32 ui32StreamIndex)3488 static VAStatus tng__cmdbuf_provide_buffer(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
3489 {
3490 VAStatus vaStatus = VA_STATUS_SUCCESS;
3491
3492 if (ctx->ui8PipesToUse == 1) {
3493 tng_send_codedbuf(ctx, ctx->ui8SlotsCoded);
3494 } else {
3495 /*Make sure DMA start is 128bits alignment*/
3496 tng_send_codedbuf(ctx, ctx->ui8SlotsCoded * 2);
3497 tng_send_codedbuf(ctx, ctx->ui8SlotsCoded * 2 + 1);
3498 }
3499
3500 if (ctx->sRCParams.ui16BFrames > 0)
3501 tng__provide_buffer_BFrames(ctx, ui32StreamIndex);
3502 else
3503 tng__provide_buffer_PFrames(ctx, ui32StreamIndex);
3504 /*
3505 if (ctx->ui32LastPicture != 0) {
3506 drv_debug_msg(VIDEO_DEBUG_GENERAL,
3507 "%s: frame_count[%d] = %d\n", __FUNCTION__,
3508 ui32StreamIndex, ctx->ui32FrameCount[ui32StreamIndex]);
3509 tng_picmgmt_update(ctx,IMG_PICMGMT_EOS, ctx->ui32LastPicture);
3510 }
3511 */
3512 #ifdef _TOPAZHP_REC_
3513 tng_send_rec_frames(ctx, -1, 0);
3514 tng_send_ref_frames(ctx, 0, 0);
3515 tng_send_ref_frames(ctx, 1, 0);
3516 #endif
3517
3518 ctx->ui8SlotsCoded = (ctx->ui8SlotsCoded + 1) & 1;
3519
3520 return vaStatus;
3521 }
3522
tng__set_ctx_buf(context_ENC_p ctx,IMG_UINT32 __maybe_unused ui32StreamID)3523 VAStatus tng__set_ctx_buf(context_ENC_p ctx, IMG_UINT32 __maybe_unused ui32StreamID)
3524 {
3525 VAStatus vaStatus = VA_STATUS_SUCCESS;
3526 IMG_UINT8 ui8IsJpeg;
3527
3528 vaStatus = tng__validate_params(ctx);
3529 if (vaStatus != VA_STATUS_SUCCESS) {
3530 drv_debug_msg(VIDEO_DEBUG_ERROR, "validate params");
3531 }
3532
3533 vaStatus = tng__validate_busize(ctx);
3534 if (vaStatus != VA_STATUS_SUCCESS) {
3535 drv_debug_msg(VIDEO_DEBUG_ERROR, "validate busize");
3536 }
3537 ctx->ctx_cmdbuf[0].ui32LowCmdCount = 0xa5a5a5a5 % MAX_TOPAZ_CMD_COUNT;
3538 ctx->ctx_cmdbuf[0].ui32HighCmdCount = 0;
3539 ctx->ctx_cmdbuf[0].ui32HighWBReceived = 0;
3540
3541 ui8IsJpeg = (ctx->eStandard == IMG_STANDARD_JPEG) ? 1 : 0;
3542 vaStatus = tng__alloc_context_buffer(ctx, ui8IsJpeg, 0);
3543 if (vaStatus != VA_STATUS_SUCCESS) {
3544 drv_debug_msg(VIDEO_DEBUG_ERROR, "setup enc profile");
3545 }
3546 return vaStatus;
3547 }
3548
tng__set_headers(context_ENC_p ctx,IMG_UINT32 __maybe_unused ui32StreamID)3549 static VAStatus tng__set_headers (context_ENC_p ctx, IMG_UINT32 __maybe_unused ui32StreamID)
3550 {
3551 VAStatus vaStatus = VA_STATUS_SUCCESS;
3552 IMG_UINT8 ui8SlotIdx = 0;
3553
3554 vaStatus = tng__prepare_templates(ctx, 0);
3555 if (vaStatus != VA_STATUS_SUCCESS) {
3556 drv_debug_msg(VIDEO_DEBUG_ERROR, "prepare_templates\n");
3557 }
3558
3559 for (ui8SlotIdx = 0; ui8SlotIdx < ctx->ui8SlotsInUse; ui8SlotIdx++)
3560 tng_fill_slice_map(ctx, (IMG_UINT32)ui8SlotIdx, 0);
3561
3562 return vaStatus;
3563 }
3564
tng__set_cmd_buf(context_ENC_p ctx,IMG_UINT32 __maybe_unused ui32StreamID)3565 static VAStatus tng__set_cmd_buf(context_ENC_p ctx, IMG_UINT32 __maybe_unused ui32StreamID)
3566 {
3567 VAStatus vaStatus = VA_STATUS_SUCCESS;
3568
3569 vaStatus = tng__cmdbuf_new_codec(ctx);
3570 if (vaStatus != VA_STATUS_SUCCESS) {
3571 drv_debug_msg(VIDEO_DEBUG_ERROR, "cmdbuf new codec\n");
3572 }
3573
3574 vaStatus = tng__cmdbuf_lowpower(ctx);
3575 if (vaStatus != VA_STATUS_SUCCESS) {
3576 drv_debug_msg(VIDEO_DEBUG_ERROR, "cmdbuf lowpower\n");
3577 }
3578
3579 vaStatus = tng__cmdbuf_load_bias(ctx);
3580 if (vaStatus != VA_STATUS_SUCCESS) {
3581 drv_debug_msg(VIDEO_DEBUG_ERROR, "cmdbuf load bias\n");
3582 }
3583
3584 vaStatus = tng__cmdbuf_setvideo(ctx, 0);
3585 if (vaStatus != VA_STATUS_SUCCESS) {
3586 drv_debug_msg(VIDEO_DEBUG_ERROR, "cmdbuf setvideo\n");
3587 }
3588 return vaStatus;
3589 }
3590
tng__end_one_frame(context_ENC_p ctx,IMG_UINT32 ui32StreamID)3591 VAStatus tng__end_one_frame(context_ENC_p ctx, IMG_UINT32 ui32StreamID)
3592 {
3593 VAStatus vaStatus = VA_STATUS_SUCCESS;
3594 context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
3595
3596 drv_debug_msg(VIDEO_DEBUG_GENERAL, "ui32StreamID is %d.\n", ui32StreamID);
3597
3598 /* save current settings */
3599 ps_buf->previous_src_surface = ps_buf->src_surface;
3600 #ifdef _TNG_FRAMES_
3601 ps_buf->previous_ref_surface = ps_buf->ref_surface;
3602 #else
3603 ps_buf->previous_ref_surface = ps_buf->ref_surface[0];
3604 #endif
3605
3606 /*Frame Skip flag in Coded Buffer of frame N determines if frame N+2
3607 * should be skipped, which means sending encoding commands of frame N+1 doesn't
3608 * have to wait until frame N is completed encoded. It reduces the precision of
3609 * rate control but improves HD encoding performance a lot.*/
3610 ps_buf->pprevious_coded_buf = ps_buf->previous_coded_buf;
3611 ps_buf->previous_coded_buf = ps_buf->coded_buf;
3612
3613 ctx->ePreFrameType = ctx->eFrameType;
3614
3615 return vaStatus;
3616 }
3617
tng_EndPicture(context_ENC_p ctx)3618 VAStatus tng_EndPicture(context_ENC_p ctx)
3619 {
3620 VAStatus vaStatus = VA_STATUS_SUCCESS;
3621 tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
3622 context_ENC_mem *ps_mem = &(ctx->ctx_mem[0]);
3623 unsigned int offset;
3624 int value;
3625
3626 drv_debug_msg(VIDEO_DEBUG_GENERAL,"%s: ctx->ui8SlicesPerPicture = %d, ctx->ui32FrameCount[0] = %d\n",
3627 __FUNCTION__, ctx->ui8SlicesPerPicture, ctx->ui32FrameCount[0]);
3628
3629 if (ctx->ui32FrameCount[0] == 0) {
3630 vaStatus = tng__set_ctx_buf(ctx, 0);
3631 if (vaStatus != VA_STATUS_SUCCESS) {
3632 drv_debug_msg(VIDEO_DEBUG_ERROR, "set ctx buf \n");
3633 }
3634 vaStatus = tng__set_headers(ctx, 0);
3635 if (vaStatus != VA_STATUS_SUCCESS) {
3636 drv_debug_msg(VIDEO_DEBUG_ERROR, "set headers \n");
3637 }
3638
3639 vaStatus = tng__set_cmd_buf(ctx, 0);
3640 if (vaStatus != VA_STATUS_SUCCESS) {
3641 drv_debug_msg(VIDEO_DEBUG_ERROR, "set cmd buf \n");
3642 }
3643
3644 #ifdef _TOPAZHP_PDUMP_
3645 tng_trace_setvideo(ctx, 0);
3646 #endif
3647 } else {
3648 vaStatus = tng__cmdbuf_lowpower(ctx);
3649 if (vaStatus != VA_STATUS_SUCCESS) {
3650 drv_debug_msg(VIDEO_DEBUG_ERROR, "cmdbuf lowpower\n");
3651 }
3652 }
3653
3654 if (ctx->sRCParams.eRCMode != IMG_RCMODE_NONE ||
3655 ctx->rc_update_flag) {
3656 vaStatus = tng__update_ratecontrol(ctx, ctx->ui32StreamID);
3657 if (vaStatus != VA_STATUS_SUCCESS) {
3658 drv_debug_msg(VIDEO_DEBUG_ERROR, "send picmgmt");
3659 }
3660 }
3661
3662 if ((ctx->idr_force_flag == 1) && (ctx->sRCParams.ui16BFrames == 0)){
3663 vaStatus = tng__update_frametype(ctx, IMG_FRAME_IDR);
3664 if (vaStatus != VA_STATUS_SUCCESS) {
3665 drv_debug_msg(VIDEO_DEBUG_ERROR, "send picmgmt IDR");
3666 }
3667 ctx->idr_force_flag =0;
3668 }
3669
3670 vaStatus = tng__cmdbuf_provide_buffer(ctx, ctx->ui32StreamID);
3671 if (vaStatus != VA_STATUS_SUCCESS) {
3672 drv_debug_msg(VIDEO_DEBUG_ERROR, "provide buffer");
3673 }
3674
3675 if (ctx->bEnableAIR == IMG_TRUE ||
3676 ctx->bEnableCIR == IMG_TRUE) {
3677 tng_air_set_input_control(ctx, 0);
3678
3679 if (ctx->bEnableAIR == IMG_TRUE)
3680 tng_air_set_output_control(ctx, 0);
3681 }
3682
3683 if (ctx->eStandard == IMG_STANDARD_MPEG4) {
3684 if (ctx->ui32FrameCount[0] == 0) {
3685 vaStatus = tng__cmdbuf_doheader(ctx);
3686 if (vaStatus != VA_STATUS_SUCCESS) {
3687 drv_debug_msg(VIDEO_DEBUG_ERROR, "cmdbuf doheader\n");
3688 }
3689 }
3690 tng__MPEG4ES_send_seq_header(ctx, ctx->ui32StreamID);
3691 }
3692
3693 if (ctx->bInsertHRDParams)
3694 tng_cmdbuf_insert_command(ctx->obj_context, ctx->ui32StreamID,
3695 MTX_CMDID_DO_HEADER, 0, &(ps_mem->bufs_sei_header), 0);
3696
3697 tng_cmdbuf_insert_command(ctx->obj_context, ctx->ui32StreamID,
3698 MTX_CMDID_ENCODE_FRAME, 0, 0, 0);
3699
3700 #ifdef _TOPAZHP_CMDBUF_
3701 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s addr = 0x%08x \n", __FUNCTION__, cmdbuf);
3702 tng__trace_cmdbuf_words(cmdbuf);
3703 tng__trace_cmdbuf(cmdbuf, ctx->ui32StreamID);
3704 #endif
3705
3706 // tng_buffer_unmap(ctx, ctx->ui32StreamID);
3707 tng_cmdbuf_mem_unmap(cmdbuf);
3708
3709 vaStatus = tng__end_one_frame(ctx, 0);
3710 if (vaStatus != VA_STATUS_SUCCESS) {
3711 drv_debug_msg(VIDEO_DEBUG_ERROR, "setting when one frame ends\n");
3712 }
3713
3714 if (tng_context_flush_cmdbuf(ctx->obj_context)) {
3715 vaStatus = VA_STATUS_ERROR_UNKNOWN;
3716 }
3717
3718
3719 ++(ctx->ui32FrameCount[ctx->ui32StreamID]);
3720 ++(ctx->ui32RawFrameCount);
3721 return vaStatus;
3722 }
3723