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