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