tng_hostcode.c revision 5bda8779f054b9e2da23725643d0559618bb5f8c
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    psb_buffer_destroy(&(ps_mem->bufs_recon_pictures));
329    psb_buffer_destroy(&(ps_mem->bufs_first_pass_out_params));
330#ifndef EXCLUDE_BEST_MP_DECISION_DATA
331    psb_buffer_destroy(&(ps_mem->bufs_first_pass_out_best_multipass_param));
332#endif
333    psb_buffer_destroy(&(ps_mem->bufs_mb_ctrl_in_params));
334    psb_buffer_destroy(&(ps_mem->bufs_lowpower_params));
335
336    return ;
337}
338
339unsigned int tng__get_ipe_control(IMG_CODEC  eEncodingFormat)
340{
341    unsigned int RegVal = 0;
342
343    RegVal = F_ENCODE(2, MVEA_CR_IPE_GRID_FINE_SEARCH) |
344    F_ENCODE(0, MVEA_CR_IPE_GRID_SEARCH_SIZE) |
345    F_ENCODE(1, MVEA_CR_IPE_Y_FINE_SEARCH);
346
347    switch (eEncodingFormat) {
348        case IMG_CODEC_H263_NO_RC:
349        case IMG_CODEC_H263_VBR:
350        case IMG_CODEC_H263_CBR:
351            RegVal |= F_ENCODE(0, MVEA_CR_IPE_BLOCKSIZE) | F_ENCODE(0, MVEA_CR_IPE_ENCODING_FORMAT);
352        break;
353        case IMG_CODEC_MPEG4_NO_RC:
354        case IMG_CODEC_MPEG4_VBR:
355        case IMG_CODEC_MPEG4_CBR:
356            RegVal |= F_ENCODE(1, MVEA_CR_IPE_BLOCKSIZE) | F_ENCODE(1, MVEA_CR_IPE_ENCODING_FORMAT);
357        default:
358        break;
359        case IMG_CODEC_H264_NO_RC:
360        case IMG_CODEC_H264_VBR:
361        case IMG_CODEC_H264_CBR:
362        case IMG_CODEC_H264_VCM:
363            RegVal |= F_ENCODE(2, MVEA_CR_IPE_BLOCKSIZE) | F_ENCODE(2, MVEA_CR_IPE_ENCODING_FORMAT);
364        break;
365    }
366    RegVal |= F_ENCODE(6, MVEA_CR_IPE_Y_CANDIDATE_NUM);
367    return RegVal;
368}
369
370void tng__setup_enc_profile_features(context_ENC_p ctx, IMG_UINT32 ui32EncProfile)
371{
372    IMG_ENCODE_FEATURES * pEncFeatures = &ctx->sEncFeatures;
373    /* Set the default values first */
374    pEncFeatures->bDisableBPicRef_0 = IMG_FALSE;
375    pEncFeatures->bDisableBPicRef_1 = IMG_FALSE;
376
377    pEncFeatures->bDisableInter8x8 = IMG_FALSE;
378    pEncFeatures->bRestrictInter4x4 = IMG_FALSE;
379
380    pEncFeatures->bDisableIntra4x4  = IMG_FALSE;
381    pEncFeatures->bDisableIntra8x8  = IMG_FALSE;
382    pEncFeatures->bDisableIntra16x16 = IMG_FALSE;
383
384    pEncFeatures->bEnable8x16MVDetect   = IMG_TRUE;
385    pEncFeatures->bEnable16x8MVDetect   = IMG_TRUE;
386    pEncFeatures->bDisableBFrames       = IMG_FALSE;
387
388    pEncFeatures->eMinBlkSz = BLK_SZ_DEFAULT;
389
390    switch (ui32EncProfile) {
391        case ENC_PROFILE_LOWCOMPLEXITY:
392            pEncFeatures->bDisableInter8x8  = IMG_TRUE;
393            pEncFeatures->bRestrictInter4x4 = IMG_TRUE;
394            pEncFeatures->bDisableIntra4x4  = IMG_TRUE;
395            pEncFeatures->bDisableIntra8x8  = IMG_TRUE;
396            pEncFeatures->bRestrictInter4x4 = IMG_TRUE;
397            pEncFeatures->eMinBlkSz         = BLK_SZ_16x16;
398            pEncFeatures->bDisableBFrames   = IMG_TRUE;
399            break;
400
401        case ENC_PROFILE_HIGHCOMPLEXITY:
402            pEncFeatures->bDisableBPicRef_0 = IMG_FALSE;
403            pEncFeatures->bDisableBPicRef_1 = IMG_FALSE;
404
405            pEncFeatures->bDisableInter8x8 = IMG_FALSE;
406            pEncFeatures->bRestrictInter4x4 = IMG_FALSE;
407
408            pEncFeatures->bDisableIntra4x4  = IMG_FALSE;
409            pEncFeatures->bDisableIntra8x8  = IMG_FALSE;
410            pEncFeatures->bDisableIntra16x16 = IMG_FALSE;
411
412            pEncFeatures->bEnable8x16MVDetect   = IMG_TRUE;
413            pEncFeatures->bEnable16x8MVDetect   = IMG_TRUE;
414            break;
415    }
416
417    if (ctx->eStandard != IMG_STANDARD_H264) {
418	pEncFeatures->bEnable8x16MVDetect = IMG_FALSE;
419	pEncFeatures->bEnable16x8MVDetect = IMG_FALSE;
420    }
421
422    return;
423}
424
425VAStatus tng__patch_hw_profile(context_ENC_p ctx)
426{
427    IMG_UINT32 ui32IPEControl = 0;
428    IMG_UINT32 ui32PredCombControl = 0;
429    IMG_ENCODE_FEATURES * psEncFeatures = &(ctx->sEncFeatures);
430
431    // bDisableIntra4x4
432    if (psEncFeatures->bDisableIntra4x4)
433        ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTRA4X4_DISABLE);
434
435    //bDisableIntra8x8
436    if (psEncFeatures->bDisableIntra8x8)
437        ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTRA8X8_DISABLE);
438
439    //bDisableIntra16x16, check if atleast one of the other Intra mode is enabled
440    if ((psEncFeatures->bDisableIntra16x16) &&
441        (!(psEncFeatures->bDisableIntra8x8) || !(psEncFeatures->bDisableIntra4x4))) {
442        ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTRA16X16_DISABLE);
443    }
444
445    if (psEncFeatures->bRestrictInter4x4) {
446//        ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTER4X4_RESTRICT);
447        ui32IPEControl |= F_ENCODE(1, TOPAZHP_CR_IPE_MV_NUMBER_RESTRICTION);
448    }
449
450    if (psEncFeatures->bDisableInter8x8)
451        ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTER8X8_DISABLE);
452
453    if (psEncFeatures->bDisableBPicRef_1)
454        ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_B_PIC1_DISABLE);
455    else if (psEncFeatures->bDisableBPicRef_0)
456        ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_B_PIC0_DISABLE);
457
458    // save predictor combiner control in video encode parameter set
459    ctx->ui32PredCombControl = ui32PredCombControl;
460
461    // set blocksize
462    ui32IPEControl |= F_ENCODE(psEncFeatures->eMinBlkSz, TOPAZHP_CR_IPE_BLOCKSIZE);
463
464    if (psEncFeatures->bEnable8x16MVDetect)
465        ui32IPEControl |= F_ENCODE(1, TOPAZHP_CR_IPE_8X16_ENABLE);
466
467    if (psEncFeatures->bEnable16x8MVDetect)
468        ui32IPEControl |= F_ENCODE(1, TOPAZHP_CR_IPE_16X8_ENABLE);
469
470    if (psEncFeatures->bDisableBFrames)
471        ctx->sRCParams.ui16BFrames = 0;
472
473    //save IPE-control register
474    ctx->ui32IPEControl = ui32IPEControl;
475
476    return VA_STATUS_SUCCESS;
477}
478
479#ifdef _TOPAZHP_CMDBUF_
480static void tng__trace_cmdbuf(tng_cmdbuf_p cmdbuf, int idx)
481{
482    IMG_UINT32 ui32CmdTmp[4];
483    IMG_UINT32 *ptmp = (IMG_UINT32 *)(cmdbuf->cmd_start);
484    IMG_UINT32 *pend = (IMG_UINT32 *)(cmdbuf->cmd_idx);
485    IMG_UINT32 ui32Len;
486
487    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);
488
489    if (idx)
490        return ;
491
492    while (ptmp < pend) {
493        drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: ptmp (0x%08x}\n", __FUNCTION__, *ptmp);
494        if ((*ptmp & 0x7f) == MTX_CMDID_SW_NEW_CODEC) {
495            ptmp += 4;
496        } else if ((*ptmp & 0x7f) == MTX_CMDID_SW_LEAVE_LOWPOWER) {
497            ptmp += 2;
498        } else if ((*ptmp & 0x7f) == MTX_CMDID_SW_WRITEREG) {
499            ui32Len = *(++ptmp);
500            drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: len = %d\n", __FUNCTION__, ui32Len);
501            ptmp += (ui32Len * 3) + 1;
502            drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: reg ptmp (0x%08x}\n", __FUNCTION__, *ptmp);
503        } else if ((*ptmp & 0x7f) == MTX_CMDID_DO_HEADER) {
504            ui32CmdTmp[0] = *ptmp++;
505            ui32CmdTmp[1] = *ptmp++;
506            ui32CmdTmp[2] = *ptmp++;
507            ui32CmdTmp[3] = 0;
508            //topazhp_dump_command((unsigned int*)ui32CmdTmp);
509            ptmp += 2;
510        } else if (
511            ((*ptmp & 0x7f) == MTX_CMDID_SETVIDEO)||
512            ((*ptmp & 0x7f) == MTX_CMDID_SHUTDOWN)) {
513            ui32CmdTmp[0] = *ptmp++;
514            ui32CmdTmp[1] = *ptmp++;
515            ui32CmdTmp[2] = *ptmp++;
516            ui32CmdTmp[3] = *ptmp++;
517            //topazhp_dump_command((unsigned int*)ui32CmdTmp);
518        } else if (
519            ((*ptmp & 0x7f) == MTX_CMDID_PROVIDE_SOURCE_BUFFER) ||
520            ((*ptmp & 0x7f) == MTX_CMDID_PROVIDE_REF_BUFFER) ||
521            ((*ptmp & 0x7f) == MTX_CMDID_PROVIDE_CODED_BUFFER) ||
522            ((*ptmp & 0x7f) == MTX_CMDID_PICMGMT) ||
523            ((*ptmp & 0x7f) == MTX_CMDID_ENCODE_FRAME)) {
524            ui32CmdTmp[0] = *ptmp++;
525            ui32CmdTmp[1] = *ptmp++;
526            ui32CmdTmp[2] = *ptmp++;
527            ui32CmdTmp[3] = 0;
528            //topazhp_dump_command((unsigned int*)ui32CmdTmp);
529        } else {
530            drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: error leave lowpower = 0x%08x\n", __FUNCTION__, *ptmp++);
531        }
532    }
533
534    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: end\n", __FUNCTION__);
535
536    return ;
537}
538#endif
539
540void tng_DestroyContext(object_context_p obj_context, unsigned char is_JPEG)
541{
542    context_ENC_p ctx;
543//    tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
544    ctx = (context_ENC_p)obj_context->format_data;
545    FRAME_ORDER_INFO *psFrameInfo = &(ctx->sFrameOrderInfo);
546
547    if (psFrameInfo->slot_consume_dpy_order != NULL)
548        free(psFrameInfo->slot_consume_dpy_order);
549    if (psFrameInfo->slot_consume_enc_order != NULL)
550        free(psFrameInfo->slot_consume_enc_order);
551
552    tng_air_buf_free(ctx);
553
554    tng__free_context_buffer(ctx, is_JPEG, 0);
555
556    if (ctx->bEnableMVC)
557        tng__free_context_buffer(ctx, is_JPEG, 1);
558
559    free(obj_context->format_data);
560    obj_context->format_data = NULL;
561}
562
563static VAStatus tng__init_rc_params(context_ENC_p ctx, object_config_p obj_config)
564{
565    IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
566    unsigned int eRCmode = 0;
567    memset(psRCParams, 0, sizeof(IMG_RC_PARAMS));
568    IMG_INT32 i;
569
570    //set RC mode
571    for (i = 0; i < obj_config->attrib_count; i++) {
572        if (obj_config->attrib_list[i].type == VAConfigAttribRateControl)
573            break;
574    }
575
576    if (i >= obj_config->attrib_count) {
577        eRCmode = VA_RC_NONE;
578    } else {
579        eRCmode = obj_config->attrib_list[i].value;
580    }
581
582    ctx->sRCParams.bRCEnable = IMG_TRUE;
583    ctx->sRCParams.bDisableBitStuffing = IMG_FALSE;
584
585    if (eRCmode == VA_RC_NONE) {
586        ctx->sRCParams.bRCEnable = IMG_FALSE;
587        ctx->sRCParams.eRCMode = IMG_RCMODE_NONE;
588    } else if (eRCmode == VA_RC_CBR) {
589        ctx->sRCParams.eRCMode = IMG_RCMODE_CBR;
590    } else if (eRCmode == VA_RC_VBR) {
591        ctx->sRCParams.eRCMode = IMG_RCMODE_VBR;
592    } else if (eRCmode == VA_RC_VCM) {
593        ctx->sRCParams.eRCMode = IMG_RCMODE_VCM;
594    } else {
595        ctx->sRCParams.bRCEnable = IMG_FALSE;
596        drv_debug_msg(VIDEO_DEBUG_ERROR, "not support this RT Format\n");
597        return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
598    }
599
600    psRCParams->bScDetectDisable = IMG_FALSE;
601    psRCParams->ui32SliceByteLimit = 0;
602    psRCParams->ui32SliceMBLimit = 0;
603    psRCParams->bIsH264Codec = (ctx->eStandard == IMG_STANDARD_H264) ? IMG_TRUE : IMG_FALSE;
604    return VA_STATUS_SUCCESS;
605}
606
607/**************************************************************************************************
608* Function:             IMG_C_GetEncoderCaps
609* Description:  Get the capabilities of the encoder for the given codec
610*
611***************************************************************************************************/
612//FIXME
613static const IMG_UINT32 g_ui32PipesAvailable = TOPAZHP_PIPE_NUM;
614static const IMG_UINT32 g_ui32CoreDes1 = TOPAZHP_PIPE_NUM;
615static const IMG_UINT32 g_ui32CoreRev = 0x00030401;
616
617static IMG_UINT32 tng__get_num_pipes()
618{
619    return g_ui32PipesAvailable;
620}
621
622static IMG_UINT32 tng__get_core_des1()
623{
624    return g_ui32CoreDes1;
625}
626
627static IMG_UINT32 tng__get_core_rev()
628{
629    return g_ui32CoreRev;
630}
631
632static VAStatus tng__get_encoder_caps(context_ENC_p ctx)
633{
634    IMG_ENC_CAPS *psCaps = &(ctx->sCapsParams);
635    IMG_UINT16 ui16Height = ctx->ui16FrameHeight;
636    IMG_UINT32 ui32NumCores = 0;
637    IMG_UINT16 ui16MBRows = 0; //MB Rows in a GOB(slice);
638
639    ctx->ui32CoreRev = tng__get_core_rev();
640    psCaps->ui32CoreFeatures = tng__get_core_des1();
641
642    /* get the actual number of cores */
643    ui32NumCores = tng__get_num_pipes();
644
645    switch (ctx->eStandard) {
646        case IMG_STANDARD_JPEG:
647            psCaps->ui16MaxSlices = ui16Height / 8;
648            psCaps->ui16MinSlices = 1;
649            psCaps->ui16RecommendedSlices = ui32NumCores;
650            break;
651        case IMG_STANDARD_H264:
652            psCaps->ui16MaxSlices = ui16Height / 16;
653            psCaps->ui16MinSlices = 1;
654            psCaps->ui16RecommendedSlices = ui32NumCores;
655            break;
656        case IMG_STANDARD_MPEG2:
657            psCaps->ui16MaxSlices = 174; // Slice labelling dictates a maximum of 174 slices
658            psCaps->ui16MinSlices = 1;
659            psCaps->ui16RecommendedSlices = (ui16Height + 15) / 16;
660            break;
661        case IMG_STANDARD_H263:
662            // if the original height of the pic is less than 400 , k is 1. refer standard.
663            if (ui16Height <= 400) {
664                ui16MBRows = 1;
665            } else if (ui16Height < 800) { // if between 400 and 800 it's 2.
666                ui16MBRows = 2;
667            } else {
668                ui16MBRows = 4;
669            }
670            // before rounding is done for the height.
671            // get the GOB's based on this MB Rows and not vice-versa.
672            psCaps->ui16RecommendedSlices = (ui16Height + 15) >> (4 + (ui16MBRows >> 1));
673            psCaps->ui16MaxSlices = psCaps->ui16MinSlices = psCaps->ui16RecommendedSlices;
674            break;
675        case IMG_STANDARD_MPEG4:
676            psCaps->ui16MaxSlices = 1;
677            psCaps->ui16MinSlices = 1;
678            psCaps->ui16RecommendedSlices = 1;
679            break;
680        default:
681            break;
682    }
683    return VA_STATUS_SUCCESS;
684}
685
686static VAStatus tng__init_context(context_ENC_p ctx)
687{
688    VAStatus vaStatus = 0;
689
690    /* Mostly sure about the following video parameters */
691    //ctx->ui32HWProfile = pParams->ui32HWProfile;
692    ctx->ui32FrameCount[0] = ctx->ui32FrameCount[1] = 0;
693    /* Using Extended parameters */
694    ctx->ui8PipesToUse = (IMG_UINT8)(tng__get_num_pipes() & (IMG_UINT32)0xff);
695    //carc params
696    ctx->sCARCParams.bCARC             = 0;
697    ctx->sCARCParams.i32CARCBaseline   = 0;
698    ctx->sCARCParams.ui32CARCThreshold = TOPAZHP_DEFAULT_uCARCThreshold;
699    ctx->sCARCParams.ui32CARCCutoff    = TOPAZHP_DEFAULT_uCARCCutoff;
700    ctx->sCARCParams.ui32CARCNegRange  = TOPAZHP_DEFAULT_uCARCNegRange;
701    ctx->sCARCParams.ui32CARCNegScale  = TOPAZHP_DEFAULT_uCARCNegScale;
702    ctx->sCARCParams.ui32CARCPosRange  = TOPAZHP_DEFAULT_uCARCPosRange;
703    ctx->sCARCParams.ui32CARCPosScale  = TOPAZHP_DEFAULT_uCARCPosScale;
704    ctx->sCARCParams.ui32CARCShift     = TOPAZHP_DEFAULT_uCARCShift;
705
706    ctx->bUseDefaultScalingList = IMG_FALSE;
707    ctx->ui32CabacBinLimit = TOPAZHP_DEFAULT_uCABACBinLimit; //This parameter need not be exposed
708    if (ctx->ui32CabacBinLimit == 0)
709        ctx->ui32CabacBinFlex = 0;//This parameter need not be exposed
710    else
711        ctx->ui32CabacBinFlex = TOPAZHP_DEFAULT_uCABACBinFlex;//This parameter need not be exposed
712
713    ctx->ui32FCode = 4;                     //This parameter need not be exposed
714    ctx->iFineYSearchSize = 2;//This parameter need not be exposed
715    ctx->ui32VopTimeResolution = 15;//This parameter need not be exposed
716//    ctx->bEnabledDynamicBPic = IMG_FALSE;//Related to Rate Control,which is no longer needed.
717    ctx->bH264IntraConstrained = IMG_FALSE;//This parameter need not be exposed
718    ctx->bEnableInpCtrl     = IMG_FALSE;//This parameter need not be exposed
719    ctx->bEnableAIR = 0;
720    ctx->bEnableCIR = 0;
721    ctx->bEnableHostBias = (ctx->bEnableAIR != 0);//This parameter need not be exposed
722    ctx->bEnableHostQP = IMG_FALSE; //This parameter need not be exposed
723    ctx->ui8CodedSkippedIndex = 3;//This parameter need not be exposed
724    ctx->ui8InterIntraIndex         = 3;//This parameter need not be exposed
725    ctx->uMaxChunks = 0xA0;//This parameter need not be exposed
726    ctx->uChunksPerMb = 0x40;//This parameter need not be exposed
727    ctx->uPriorityChunks = (0xA0 - 0x60);//This parameter need not be exposed
728    ctx->bWeightedPrediction = IMG_FALSE;//Weighted Prediction is not supported in TopazHP Version 3.0
729    ctx->ui8VPWeightedImplicitBiPred = 0;//Weighted Prediction is not supported in TopazHP Version 3.0
730    ctx->bSkipDuplicateVectors = IMG_FALSE;//By default false Newly Added
731    ctx->bEnableCumulativeBiases = IMG_FALSE;//By default false Newly Added
732    ctx->ui16UseCustomScalingLists = 0;//By default false Newly Added
733    ctx->bPpsScaling = IMG_FALSE;//By default false Newly Added
734    ctx->ui8MPEG2IntraDCPrecision = 0;//By default 0 Newly Added
735    ctx->uMBspS = 0;//By default 0 Newly Added
736    ctx->bMultiReferenceP = IMG_FALSE;//By default false Newly Added
737    ctx->ui8RefSpacing=0;//By default 0 Newly Added
738    ctx->bSpatialDirect = 0;//By default 0 Newly Added
739    ctx->ui32DebugCRCs = 0;//By default false Newly Added
740    ctx->bEnableMVC = IMG_FALSE;//By default false Newly Added
741    ctx->ui16MVCViewIdx = (IMG_UINT16)(NON_MVC_VIEW);//Newly Added
742    ctx->bSrcAllocInternally = IMG_FALSE;//By default false Newly Added
743    ctx->bCodedAllocInternally = IMG_FALSE;//By default true Newly Added
744    ctx->bHighLatency = IMG_TRUE;//Newly Added
745    ctx->i32NumAIRMBs = -1;
746    ctx->i32AIRThreshold = -1;
747    ctx->i16AIRSkipCnt = -1;
748    ctx->i32LastCIRIndex = -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 < 5) {
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                        i32TmpQp -= 6;
1431                }
1432            } else
1433                i32TmpQp = psRCParams->iMinQP;
1434
1435            if (i32TmpQp < 2) {
1436                psPicParams->sInParams.ui8MinQPVal = 2;
1437            } else {
1438                psPicParams->sInParams.ui8MinQPVal = i32TmpQp;
1439            }
1440
1441            // Calculate Initial QP if it has not been specified
1442            i32TmpQp = psPicParams->sInParams.ui8SeInitQP;
1443            if (psPicParams->sInParams.ui8SeInitQP==0) {
1444                L1 = 0.050568;
1445                L2 = 0.202272;
1446                L3 = 0.40454321;
1447                L4 = 0.80908642;
1448                L5 = 1.011358025;
1449
1450                if (flBpp < L1)
1451                    i32TmpQp = (IMG_INT32)(45 - 78.10*flBpp);
1452                else if (flBpp>=L1 && flBpp<L2)
1453                    i32TmpQp = (IMG_INT32)(44 - 72.51*flBpp);
1454                else if (flBpp>=L2 && flBpp<L3)
1455                    i32TmpQp = (IMG_INT32)(34 - 24.72*flBpp);
1456                else if (flBpp>=L3 && flBpp<L4)
1457                    i32TmpQp = (IMG_INT32)(32 - 19.78*flBpp);
1458                else if (flBpp>=L4 && flBpp<L5)
1459                    i32TmpQp = (IMG_INT32)(25 - 9.89*flBpp);
1460                else if (flBpp>=L5)
1461                    i32TmpQp = (IMG_INT32)(18 - 4.95*flBpp);
1462
1463                /* Adjust ui8SeInitQP up for small buffer size or small fps */
1464                /* Adjust ui8SeInitQP up for small gop size */
1465                if ((i32BufferSizeInFrames < 20) || (psRCParams->ui32IntraFreq < 20)) {
1466                    i32TmpQp += 2;
1467                }
1468
1469		/* for very small buffers increase initial Qp even more */
1470		if(i32BufferSizeInFrames < 5)
1471		{
1472			i32TmpQp += 8;
1473		}
1474
1475                /* start on a lower initial Qp for HD content as the coding is more efficient */
1476                if (psPicParams->sInParams.ui16MBPerFrm > 2000) {
1477                    i32TmpQp -= 2;
1478                }
1479
1480		if(psPicParams->sInParams.ui16IntraPeriod ==1)
1481		{
1482		    /* for very small GOPS start with a much higher initial Qp */
1483		    i32TmpQp += 12;
1484		} else if (psPicParams->sInParams.ui16IntraPeriod<5) {
1485		    /* for very small GOPS start with a much higher initial Qp */
1486		    i32TmpQp += 6;
1487		}
1488            }
1489            if (i32TmpQp>49) {
1490                i32TmpQp = 49;
1491            }
1492            if (i32TmpQp < psPicParams->sInParams.ui8MinQPVal) {
1493                i32TmpQp = psPicParams->sInParams.ui8MinQPVal;
1494            }
1495            psPicParams->sInParams.ui8SeInitQP = i32TmpQp;
1496
1497            if(flBpp <= 0.3)
1498                psPicParams->ui32Flags |= ISRC_I16BIAS;
1499
1500            break;
1501
1502        case IMG_STANDARD_MPEG4:
1503        case IMG_STANDARD_MPEG2:
1504        case IMG_STANDARD_H263:
1505            psPicParams->sInParams.ui8MaxQPVal	 = 31;
1506            if (ctx->ui16Width == 176) {
1507                L1 = 0.042;    L2 = 0.084;    L3 = 0.126;    L4 = 0.168;    L5 = 0.336;    L6=0.505;
1508            } else if (ctx->ui16Width == 352) {
1509                L1 = 0.064;    L2 = 0.084;    L3 = 0.106;    L4 = 0.126;    L5 = 0.168;    L6=0.210;
1510            } else {
1511                L1 = 0.050;    L2 = 0.0760;    L3 = 0.096;   L4 = 0.145;    L5 = 0.193;    L6=0.289;
1512            }
1513
1514            if (psPicParams->sInParams.ui8SeInitQP==0) {
1515                if (flBpp < L1)
1516                    psPicParams->sInParams.ui8SeInitQP = 31;
1517                else if (flBpp>=L1 && flBpp<L2)
1518                    psPicParams->sInParams.ui8SeInitQP = 26;
1519                else if (flBpp>=L2 && flBpp<L3)
1520                    psPicParams->sInParams.ui8SeInitQP = 22;
1521                else if (flBpp>=L3 && flBpp<L4)
1522                    psPicParams->sInParams.ui8SeInitQP = 18;
1523                else if (flBpp>=L4 && flBpp<L5)
1524                    psPicParams->sInParams.ui8SeInitQP = 14;
1525                else if (flBpp>=L5 && flBpp<L6)
1526                    psPicParams->sInParams.ui8SeInitQP = 10;
1527                else
1528                    psPicParams->sInParams.ui8SeInitQP = 8;
1529
1530                /* Adjust ui8SeInitQP up for small buffer size or small fps */
1531                /* Adjust ui8SeInitQP up for small gop size */
1532                if ((i32BufferSizeInFrames < 20) || (psRCParams->ui32IntraFreq < 20)) {
1533                    psPicParams->sInParams.ui8SeInitQP += 2;
1534                }
1535
1536                if (psPicParams->sInParams.ui8SeInitQP > psPicParams->sInParams.ui8MaxQPVal) {
1537                    psPicParams->sInParams.ui8SeInitQP = psPicParams->sInParams.ui8MaxQPVal;
1538                }
1539                psPicParams->sInParams.mode.other.ui16AvQPVal =  psPicParams->sInParams.ui8SeInitQP;
1540            }
1541            psPicParams->sInParams.ui8MinQPVal = 2;
1542
1543            /* Adjust minQp up for small buffer size and down for large buffer size */
1544            if (i32BufferSizeInFrames < 20) {
1545                psPicParams->sInParams.ui8MinQPVal += 1;
1546            }
1547            break;
1548
1549        default:
1550            /* the NO RC cases will fall here */
1551            break;
1552    }
1553
1554    if (ctx->sRCParams.eRCMode == IMG_RCMODE_VBR) {
1555        psPicParams->sInParams.ui16MBPerBU  = psPicParams->sInParams.ui16MBPerFrm;
1556        psPicParams->sInParams.ui16BUPerFrm = 1;
1557
1558        // Initialize the parameters of fluid flow traffic model.
1559        psPicParams->sInParams.i32BufferSize   = psRCParams->ui32BufferSize;
1560
1561
1562        // These scale factor are used only for rate control to avoid overflow
1563        // in fixed-point calculation these scale factors are decided by bit rate
1564        if (psRCParams->ui32BitsPerSecond < 640000) {
1565            psPicParams->sInParams.ui8ScaleFactor  = 2;						// related to complexity
1566        }
1567        else if (psRCParams->ui32BitsPerSecond < 2000000) {
1568            // 2 Mbits
1569            psPicParams->sInParams.ui8ScaleFactor  = 4;
1570        }
1571        else if(psRCParams->ui32BitsPerSecond < 8000000) {
1572            // 8 Mbits
1573            psPicParams->sInParams.ui8ScaleFactor  = 6;
1574        } else
1575            psPicParams->sInParams.ui8ScaleFactor  = 8;
1576    } else {
1577        // Set up Input Parameters that are mode dependent
1578        switch (ctx->eStandard) {
1579            case IMG_STANDARD_H264:
1580                // ------------------- H264 CBR RC ------------------- //
1581                // Initialize the parameters of fluid flow traffic model.
1582                psPicParams->sInParams.i32BufferSize = psRCParams->ui32BufferSize;
1583
1584                // HRD consideration - These values are used by H.264 reference code.
1585                if (psRCParams->ui32BitsPerSecond < 1000000) {
1586                // 1 Mbits/s
1587                    psPicParams->sInParams.ui8ScaleFactor = 0;
1588                } else if (psRCParams->ui32BitsPerSecond < 2000000) {
1589                // 2 Mbits/s
1590                    psPicParams->sInParams.ui8ScaleFactor = 1;
1591                } else if (psRCParams->ui32BitsPerSecond < 4000000) {
1592                // 4 Mbits/s
1593                    psPicParams->sInParams.ui8ScaleFactor = 2;
1594                } else if (psRCParams->ui32BitsPerSecond < 8000000) {
1595                // 8 Mbits/s
1596                    psPicParams->sInParams.ui8ScaleFactor = 3;
1597                } else  {
1598                    psPicParams->sInParams.ui8ScaleFactor = 4;
1599                }
1600
1601                if (ctx->sRCParams.eRCMode == IMG_RCMODE_VCM) {
1602                    psPicParams->sInParams.i32BufferSize = i32BufferSizeInFrames;
1603                }
1604                break;
1605            case IMG_STANDARD_MPEG4:
1606            case IMG_STANDARD_MPEG2:
1607            case IMG_STANDARD_H263:
1608                flBpp  = 256 * (psRCParams->ui32BitsPerSecond/ctx->ui16Width);
1609                flBpp /= (ctx->ui16FrameHeight * psRCParams->ui32FrameRate);
1610
1611                if ((psPicParams->sInParams.ui16MBPerFrm > 1024 && flBpp < 16) || (psPicParams->sInParams.ui16MBPerFrm <= 1024 && flBpp < 24))
1612                    psPicParams->sInParams.mode.other.ui8HalfFrameRate = 1;
1613                else
1614                    psPicParams->sInParams.mode.other.ui8HalfFrameRate = 0;
1615
1616                if (psPicParams->sInParams.mode.other.ui8HalfFrameRate >= 1) {
1617                    psPicParams->sInParams.ui8SeInitQP = 31;
1618                    psPicParams->sInParams.mode.other.ui16AvQPVal = 31;
1619                    psPicParams->sInParams.mode.other.ui16MyInitQP = 31;
1620                }
1621
1622                psPicParams->sInParams.i32BufferSize = psRCParams->ui32BufferSize;
1623                break;
1624            default:
1625                break;
1626        }
1627    }
1628
1629    if (psRCParams->bScDetectDisable)
1630        psPicParams->ui32Flags  |= ISSCENE_DISABLED;
1631
1632    psPicParams->sInParams.i32InitialDelay	= psRCParams->i32InitialDelay;
1633    psPicParams->sInParams.i32InitialLevel	= psRCParams->i32InitialLevel;
1634    psRCParams->ui32InitialQp = psPicParams->sInParams.ui8SeInitQP;
1635
1636    /* The rate control uses this value to adjust the reaction rate to larger than expected frames */
1637    if (ctx->eStandard == IMG_STANDARD_H264) {
1638        if (psPicParams->sInParams.i32BitsPerFrm) {
1639            const IMG_INT32 bitsPerGop = (psRCParams->ui32BitsPerSecond / psRCParams->ui32FrameRate) * psRCParams->ui32IntraFreq;
1640            psPicParams->sInParams.mode.h264.ui32RCScaleFactor = (bitsPerGop * 256) /
1641                (psPicParams->sInParams.i32BufferSize - psPicParams->sInParams.i32InitialLevel);
1642        } else {
1643            psPicParams->sInParams.mode.h264.ui32RCScaleFactor = 0;
1644        }
1645    } else {
1646        psPicParams->sInParams.mode.other.ui16MyInitQP		= psPicParams->sInParams.ui8SeInitQP;
1647    }
1648
1649    return ;
1650}
1651
1652static void tng__save_slice_params_template(
1653    context_ENC_p ctx,
1654    IMG_UINT32  ui32SliceBufIdx,
1655    IMG_UINT32  ui32SliceType,
1656    IMG_UINT32  ui32IPEControl,
1657    IMG_UINT32  ui32Flags,
1658    IMG_UINT32  ui32SliceConfig,
1659    IMG_UINT32  ui32SeqConfig,
1660    IMG_UINT32  ui32StreamIndex
1661)
1662{
1663    IMG_FRAME_TEMPLATE_TYPE eSliceType = (IMG_FRAME_TEMPLATE_TYPE)ui32SliceType;
1664    context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
1665    SLICE_PARAMS *slice_temp_p = NULL;
1666
1667    psb_buffer_map(&(ps_mem->bufs_slice_template), &(ps_mem->bufs_slice_template.virtual_addr));
1668    if (ps_mem->bufs_slice_template.virtual_addr == NULL) {
1669        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping slice template\n", __FUNCTION__);
1670        return ;
1671    }
1672
1673    slice_temp_p = (SLICE_PARAMS*)(ps_mem->bufs_slice_template.virtual_addr + (ctx->ctx_mem_size.slice_template * ui32SliceBufIdx));
1674
1675    slice_temp_p->eTemplateType = eSliceType;
1676    slice_temp_p->ui32Flags = ui32Flags;
1677    slice_temp_p->ui32IPEControl = ui32IPEControl;
1678    slice_temp_p->ui32SliceConfig = ui32SliceConfig;
1679    slice_temp_p->ui32SeqConfig = ui32SeqConfig;
1680
1681    psb_buffer_unmap(&(ps_mem->bufs_slice_template));
1682
1683    return ;
1684}
1685
1686
1687/*****************************************************************************
1688 * Function Name        :       PrepareEncodeSliceParams
1689 *
1690 ****************************************************************************/
1691static IMG_UINT32 tng__prepare_encode_sliceparams(
1692    context_ENC_p ctx,
1693    IMG_UINT32  ui32SliceBufIdx,
1694    IMG_UINT32  ui32SliceType,
1695    IMG_UINT16  ui16CurrentRow,
1696    IMG_UINT16  ui16SliceHeight,
1697    IMG_UINT8   uiDeblockIDC,
1698    IMG_BOOL    bFieldMode,
1699    IMG_INT     iFineYSearchSize,
1700    IMG_UINT32  ui32StreamIndex
1701)
1702{
1703    IMG_UINT32      ui32FrameStoreFormat;
1704    IMG_UINT8       ui8SwapChromas;
1705    IMG_UINT32      ui32MBsPerKick, ui32KicksPerSlice;
1706    IMG_UINT32      ui32IPEControl;
1707    IMG_UINT32      ui32Flags = 0;
1708    IMG_UINT32      ui32SliceConfig = 0;
1709    IMG_UINT32      ui32SeqConfig = 0;
1710    IMG_BOOL bIsIntra = IMG_FALSE;
1711    IMG_BOOL bIsBPicture = IMG_FALSE;
1712    IMG_BOOL bIsIDR = IMG_FALSE;
1713    IMG_IPE_MINBLOCKSIZE blkSz;
1714    IMG_FRAME_TEMPLATE_TYPE eSliceType = (IMG_FRAME_TEMPLATE_TYPE)ui32SliceType;
1715
1716    if (!ctx) {
1717        return VA_STATUS_ERROR_INVALID_CONTEXT;
1718    }
1719
1720    /* We want multiple ones of these so we can submit multiple slices without having to wait for the next*/
1721    ui32IPEControl = ctx->ui32IPEControl;
1722    bIsIntra = ((eSliceType == IMG_FRAME_IDR) || (eSliceType == IMG_FRAME_INTRA));
1723    bIsBPicture = (eSliceType == IMG_FRAME_INTER_B);
1724    bIsIDR = ((eSliceType == IMG_FRAME_IDR) || (eSliceType == IMG_FRAME_INTER_P_IDR));
1725
1726    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG bIsIntra  = %x\n", __FUNCTION__, bIsIntra);
1727    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG bIsBFrame = %x\n", __FUNCTION__, bIsBPicture);
1728    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG bIsIDR    = %x\n", __FUNCTION__, bIsIDR);
1729    /* extract block size */
1730    blkSz = F_EXTRACT(ui32IPEControl, TOPAZHP_CR_IPE_BLOCKSIZE);
1731    /* mask-out the block size bits from ui32IPEControl */
1732    ui32IPEControl &= ~(F_MASK(TOPAZHP_CR_IPE_BLOCKSIZE));
1733    switch (ctx->eStandard) {
1734    case IMG_STANDARD_NONE:
1735    case IMG_STANDARD_JPEG:
1736        break;
1737
1738    case IMG_STANDARD_H264:
1739        if (blkSz > 2) blkSz = 2;
1740        if (bIsBPicture) {
1741            if (blkSz > 1) blkSz = 1;
1742        }
1743#ifdef BRN_30322
1744        else if (bIsIntra) {
1745            if (blkSz == 0) blkSz = 1; // Workaround for BRN 30322
1746        }
1747#endif
1748
1749#ifdef BRN_30550
1750        if (ctx->bCabacEnabled)
1751            if (blkSz == 0) blkSz = 1;
1752#endif
1753        if (ctx->uMBspS >= _1080P_30FPS) {
1754            ui32IPEControl |= F_ENCODE(iFineYSearchSize, TOPAZHP_CR_IPE_LRITC_BOUNDARY) |
1755                              F_ENCODE(iFineYSearchSize, TOPAZHP_CR_IPE_Y_FINE_SEARCH);
1756        } else {
1757            ui32IPEControl |= F_ENCODE(iFineYSearchSize + 1, TOPAZHP_CR_IPE_LRITC_BOUNDARY) |
1758                              F_ENCODE(iFineYSearchSize, TOPAZHP_CR_IPE_Y_FINE_SEARCH);
1759
1760        }
1761        if (ctx->bLimitNumVectors)
1762            ui32IPEControl |= F_ENCODE(1, TOPAZHP_CR_IPE_MV_NUMBER_RESTRICTION);
1763        break;
1764
1765    case IMG_STANDARD_H263:
1766        blkSz = 0;
1767        ui32IPEControl = F_ENCODE(iFineYSearchSize + 1, TOPAZHP_CR_IPE_LRITC_BOUNDARY) |
1768                         F_ENCODE(iFineYSearchSize, TOPAZHP_CR_IPE_Y_FINE_SEARCH) |
1769                         F_ENCODE(0, TOPAZHP_CR_IPE_4X4_SEARCH);
1770        //We only support a maxium vector of 15.5 pixels in H263
1771        break;
1772
1773    case IMG_STANDARD_MPEG4:
1774        if (blkSz > BLK_SZ_8x8) blkSz = BLK_SZ_8x8;
1775        ui32IPEControl |= F_ENCODE(iFineYSearchSize + 1, TOPAZHP_CR_IPE_LRITC_BOUNDARY) |
1776                          F_ENCODE(iFineYSearchSize, TOPAZHP_CR_IPE_Y_FINE_SEARCH) |
1777                          F_ENCODE(0, TOPAZHP_CR_IPE_4X4_SEARCH);
1778        // FIXME Should be 1, set to zero for hardware testing.
1779        break;
1780    case IMG_STANDARD_MPEG2:
1781        if (blkSz != BLK_SZ_16x16) blkSz = BLK_SZ_16x16;
1782        ui32IPEControl |= F_ENCODE(iFineYSearchSize + 1, TOPAZHP_CR_IPE_LRITC_BOUNDARY) |
1783                          F_ENCODE(iFineYSearchSize, TOPAZHP_CR_IPE_Y_FINE_SEARCH) |
1784                          F_ENCODE(0, TOPAZHP_CR_IPE_4X4_SEARCH);
1785        // FIXME Should be 1, set to zero for hardware testing.
1786        break;
1787    }
1788
1789    {
1790        IMG_BOOL bRestrict4x4SearchSize;
1791        IMG_UINT32 uLritcBoundary;
1792
1793        if (ctx->uMBspS >= _1080P_30FPS)
1794            bRestrict4x4SearchSize = 1;
1795        else
1796            bRestrict4x4SearchSize = 0;
1797
1798        ui32IPEControl |= F_ENCODE(blkSz, TOPAZHP_CR_IPE_BLOCKSIZE);
1799        uLritcBoundary = (blkSz != BLK_SZ_16x16) ? (iFineYSearchSize + (bRestrict4x4SearchSize ? 0 : 1)) : 1;
1800        if (uLritcBoundary > 3) {
1801            return VA_STATUS_ERROR_UNKNOWN;
1802        }
1803
1804        /* Minium sub block size to calculate motion vectors for. 0=16x16, 1=8x8, 2=4x4 */
1805        ui32IPEControl = F_INSERT(ui32IPEControl, blkSz, TOPAZHP_CR_IPE_BLOCKSIZE);
1806        ui32IPEControl = F_INSERT(ui32IPEControl, iFineYSearchSize, TOPAZHP_CR_IPE_Y_FINE_SEARCH);
1807        ui32IPEControl = F_INSERT(ui32IPEControl, ctx->bLimitNumVectors, TOPAZHP_CR_IPE_MV_NUMBER_RESTRICTION);
1808
1809        ui32IPEControl = F_INSERT(ui32IPEControl, uLritcBoundary, TOPAZHP_CR_IPE_LRITC_BOUNDARY);  // 8x8 search
1810        ui32IPEControl = F_INSERT(ui32IPEControl, bRestrict4x4SearchSize ? 0 : 1, TOPAZHP_CR_IPE_4X4_SEARCH);
1811
1812    }
1813    ui32IPEControl = F_INSERT(ui32IPEControl, ctx->bHighLatency, TOPAZHP_CR_IPE_HIGH_LATENCY);
1814//              psSliceParams->ui32IPEControl = ui32IPEControl;
1815
1816    if (!bIsIntra) {
1817        if (bIsBPicture)
1818            ui32Flags |= ISINTERB_FLAGS;
1819        else
1820            ui32Flags |= ISINTERP_FLAGS;
1821    }
1822    switch (ctx->eStandard)  {
1823    case IMG_STANDARD_NONE:
1824        break;
1825    case IMG_STANDARD_H263:
1826        ui32Flags |= ISH263_FLAGS;
1827        break;
1828    case IMG_STANDARD_MPEG4:
1829        ui32Flags |= ISMPEG4_FLAGS;
1830        break;
1831    case IMG_STANDARD_MPEG2:
1832        ui32Flags |= ISMPEG2_FLAGS;
1833        break;
1834    default:
1835        break;
1836    }
1837
1838    if (ctx->bMultiReferenceP && !(bIsIntra || bIsBPicture))
1839        ui32Flags |= ISMULTIREF_FLAGS;
1840    if (ctx->bSpatialDirect && bIsBPicture)
1841        ui32Flags |= SPATIALDIRECT_FLAGS;
1842
1843    if (bIsIntra) {
1844        ui32SliceConfig = F_ENCODE(TOPAZHP_CR_SLICE_TYPE_I_SLICE, TOPAZHP_CR_SLICE_TYPE);
1845    } else {
1846        if (bIsBPicture) {
1847            ui32SliceConfig = F_ENCODE(TOPAZHP_CR_SLICE_TYPE_B_SLICE, TOPAZHP_CR_SLICE_TYPE);
1848        } else {
1849            // p frame
1850            ui32SliceConfig = F_ENCODE(TOPAZHP_CR_SLICE_TYPE_P_SLICE, TOPAZHP_CR_SLICE_TYPE);
1851        }
1852    }
1853
1854    ui32MBsPerKick = ctx->ui32KickSize;
1855    // we need to figure out the number of kicks and mb's per kick to use.
1856    // on H.264 we will use a MB's per kick of basic unit
1857    // on other rc varients we will use mb's per kick of width
1858    ui32KicksPerSlice = ((ui16SliceHeight / 16) * (ctx->ui16Width / 16)) / ui32MBsPerKick;
1859    assert((ui32KicksPerSlice * ui32MBsPerKick) == ((ui16SliceHeight / 16)*(ctx->ui16Width / 16)));
1860
1861    // need some sensible ones don't look to be implemented yet...
1862    // change per stream
1863
1864    if ((ctx->eFormat == IMG_CODEC_UY0VY1_8888) || (ctx->eFormat == IMG_CODEC_VY0UY1_8888))
1865        ui32FrameStoreFormat = 3;
1866    else if ((ctx->eFormat == IMG_CODEC_Y0UY1V_8888) || (ctx->eFormat == IMG_CODEC_Y0VY1U_8888))
1867        ui32FrameStoreFormat = 2;
1868    else if ((ctx->eFormat == IMG_CODEC_PL12) || (ctx->eFormat == IMG_CODEC_422_PL12))
1869        ui32FrameStoreFormat = 1;
1870    else
1871        ui32FrameStoreFormat = 0;
1872
1873    if ((ctx->eFormat == IMG_CODEC_VY0UY1_8888) || (ctx->eFormat == IMG_CODEC_Y0VY1U_8888))
1874        ui8SwapChromas = 1;
1875    else
1876        ui8SwapChromas = 0;
1877
1878    switch (ctx->eStandard) {
1879    case IMG_STANDARD_NONE:
1880    case IMG_STANDARD_JPEG:
1881        break;
1882    case IMG_STANDARD_H264:
1883        /* H264 */
1884
1885        ui32SeqConfig = F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC0_BELOW_IN_VALID)
1886                        | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC1_BELOW_IN_VALID)
1887                        | F_ENCODE(0, TOPAZHP_CR_ABOVE_OUT_OF_SLICE_VALID)
1888                        | F_ENCODE(1, TOPAZHP_CR_WRITE_TEMPORAL_PIC0_BELOW_VALID)
1889                        | F_ENCODE(0, TOPAZHP_CR_REF_PIC0_VALID)
1890                        | F_ENCODE(0, TOPAZHP_CR_REF_PIC1_VALID)
1891                        | F_ENCODE(!bIsBPicture, TOPAZHP_CR_REF_PIC1_EQUAL_PIC0)
1892                        | F_ENCODE(bFieldMode ? 1 : 0 , TOPAZHP_CR_FIELD_MODE)
1893                        | F_ENCODE(ui8SwapChromas, TOPAZHP_CR_FRAME_STORE_CHROMA_SWAP)
1894                        | F_ENCODE(ui32FrameStoreFormat, TOPAZHP_CR_FRAME_STORE_FORMAT)
1895                        | F_ENCODE(TOPAZHP_CR_ENCODER_STANDARD_H264, TOPAZHP_CR_ENCODER_STANDARD)
1896                        | F_ENCODE(uiDeblockIDC == 1 ? 0 : 1, TOPAZHP_CR_DEBLOCK_ENABLE);
1897
1898        if (ctx->sRCParams.ui16BFrames) {
1899            ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_WRITE_TEMPORAL_COL_VALID);
1900            if ((ui32Flags & ISINTERB_FLAGS) == ISINTERB_FLAGS)
1901                ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_TEMPORAL_COL_IN_VALID);
1902        }
1903
1904        if (!bIsBPicture) {
1905            ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_WRITE_TEMPORAL_COL_VALID);
1906        }
1907
1908        break;
1909    case IMG_STANDARD_MPEG4:
1910        /* MPEG4 */
1911        ui32SeqConfig = F_ENCODE(1, TOPAZHP_CR_WRITE_RECON_PIC)
1912                        | F_ENCODE(0, TOPAZHP_CR_DEBLOCK_ENABLE)
1913                        | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC0_BELOW_IN_VALID)
1914                        | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC1_BELOW_IN_VALID)
1915                        | F_ENCODE(0, TOPAZHP_CR_ABOVE_OUT_OF_SLICE_VALID)
1916                        | F_ENCODE(((ui32Flags & ISINTERP_FLAGS) == ISINTERP_FLAGS), TOPAZHP_CR_WRITE_TEMPORAL_PIC0_BELOW_VALID)
1917                        | F_ENCODE(0, TOPAZHP_CR_REF_PIC0_VALID)
1918                        | F_ENCODE(0, TOPAZHP_CR_REF_PIC1_VALID)
1919                        | F_ENCODE(1, TOPAZHP_CR_REF_PIC1_EQUAL_PIC0)
1920                        | F_ENCODE(0, TOPAZHP_CR_FIELD_MODE)
1921                        | F_ENCODE(ui8SwapChromas, TOPAZHP_CR_FRAME_STORE_CHROMA_SWAP)
1922                        | F_ENCODE(ui32FrameStoreFormat, TOPAZHP_CR_FRAME_STORE_FORMAT)
1923                        | F_ENCODE(TOPAZHP_CR_ENCODER_STANDARD_MPEG4, TOPAZHP_CR_ENCODER_STANDARD);
1924        break;
1925    case IMG_STANDARD_MPEG2:
1926        /* MPEG2 */
1927        ui32SeqConfig = F_ENCODE(1, TOPAZHP_CR_WRITE_RECON_PIC)
1928                        | F_ENCODE(0, TOPAZHP_CR_DEBLOCK_ENABLE)
1929                        | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC0_BELOW_IN_VALID)
1930                        | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC1_BELOW_IN_VALID)
1931                        | F_ENCODE(0, TOPAZHP_CR_ABOVE_OUT_OF_SLICE_VALID)
1932                        | F_ENCODE(((ui32Flags & ISINTERP_FLAGS) == ISINTERP_FLAGS), TOPAZHP_CR_WRITE_TEMPORAL_PIC0_BELOW_VALID)
1933                        | F_ENCODE(1, TOPAZHP_CR_REF_PIC0_VALID)
1934                        | F_ENCODE(0, TOPAZHP_CR_REF_PIC1_VALID)
1935                        | F_ENCODE(1, TOPAZHP_CR_REF_PIC1_EQUAL_PIC0)
1936                        | F_ENCODE(bFieldMode ? 1 : 0 , TOPAZHP_CR_FIELD_MODE)
1937                        | F_ENCODE(ui8SwapChromas, TOPAZHP_CR_FRAME_STORE_CHROMA_SWAP)
1938                        | F_ENCODE(ui32FrameStoreFormat, TOPAZHP_CR_FRAME_STORE_FORMAT)
1939                        | F_ENCODE(TOPAZHP_CR_ENCODER_STANDARD_MPEG2, TOPAZHP_CR_ENCODER_STANDARD);
1940        break;
1941    case IMG_STANDARD_H263:
1942        /* H263 */
1943        ui32SeqConfig = F_ENCODE(1, TOPAZHP_CR_WRITE_RECON_PIC)
1944                        | F_ENCODE(0, TOPAZHP_CR_DEBLOCK_ENABLE)
1945                        | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC0_BELOW_IN_VALID)
1946                        | F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC1_BELOW_IN_VALID)
1947                        | F_ENCODE(0, TOPAZHP_CR_ABOVE_OUT_OF_SLICE_VALID)
1948                        | F_ENCODE(((ui32Flags & ISINTERP_FLAGS) == ISINTERP_FLAGS), TOPAZHP_CR_WRITE_TEMPORAL_PIC0_BELOW_VALID)
1949                        | F_ENCODE(0, TOPAZHP_CR_REF_PIC0_VALID)
1950                        | F_ENCODE(0, TOPAZHP_CR_REF_PIC1_VALID)
1951                        | F_ENCODE(1, TOPAZHP_CR_REF_PIC1_EQUAL_PIC0)
1952                        | F_ENCODE(0, TOPAZHP_CR_FIELD_MODE)
1953                        | F_ENCODE(ui8SwapChromas, TOPAZHP_CR_FRAME_STORE_CHROMA_SWAP)
1954                        | F_ENCODE(ui32FrameStoreFormat, TOPAZHP_CR_FRAME_STORE_FORMAT)
1955                        | F_ENCODE(TOPAZHP_CR_ENCODER_STANDARD_H263, TOPAZHP_CR_ENCODER_STANDARD);
1956        break;
1957    }
1958
1959    if (bIsBPicture)        {
1960        ui32SeqConfig |= F_ENCODE(0, TOPAZHP_CR_TEMPORAL_PIC1_BELOW_IN_VALID)
1961                         | F_ENCODE(0, TOPAZHP_CR_WRITE_TEMPORAL_PIC1_BELOW_VALID)
1962                         | F_ENCODE(1, TOPAZHP_CR_REF_PIC1_VALID)
1963                         | F_ENCODE(1, TOPAZHP_CR_TEMPORAL_COL_IN_VALID);
1964    }
1965
1966    if (ctx->ui8EnableSelStatsFlags & ESF_FIRST_STAGE_STATS)        {
1967        ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_WRITE_MB_FIRST_STAGE_VALID);
1968    }
1969
1970    if (ctx->ui8EnableSelStatsFlags & ESF_MP_BEST_MB_DECISION_STATS ||
1971        ctx->ui8EnableSelStatsFlags & ESF_MP_BEST_MOTION_VECTOR_STATS)  {
1972        ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_BEST_MULTIPASS_OUT_VALID);
1973
1974        if (!(ctx->ui8EnableSelStatsFlags & ESF_MP_BEST_MOTION_VECTOR_STATS)) {
1975            ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_BEST_MVS_OUT_DISABLE);// 64 Byte Best Multipass Motion Vector output disabled by default
1976        }
1977    }
1978
1979    if (ctx->bEnableInpCtrl) {
1980        ui32SeqConfig |= F_ENCODE(1, TOPAZHP_CR_MB_CONTROL_IN_VALID);
1981    }
1982
1983    if (eSliceType == IMG_FRAME_IDR) {
1984        ctx->sBiasTables.ui32SeqConfigInit = ui32SeqConfig;
1985    }
1986
1987    tng__save_slice_params_template(ctx, ui32SliceBufIdx, eSliceType,
1988        ui32IPEControl, ui32Flags, ui32SliceConfig, ui32SeqConfig, ui32StreamIndex);
1989
1990    return 0;
1991}
1992
1993void tng__mpeg4_generate_pic_hdr_template(
1994    context_ENC_p ctx,
1995    IMG_FRAME_TEMPLATE_TYPE ui8SliceType,
1996    IMG_UINT8 ui8Search_range)
1997{
1998    context_ENC_mem *ps_mem = &(ctx->ctx_mem[ctx->ui32StreamID]);
1999    MTX_HEADER_PARAMS * pPicHeaderMem;
2000    VOP_CODING_TYPE eVop_Coding_Type;
2001    IMG_BOOL8 b8IsVopCoded;
2002    IMG_UINT8 ui8OriginalSliceType = ui8SliceType;
2003
2004    /* MPEG4: We do not support B-frames at the moment, so we use a spare slot, to store a template for the skipped frame */
2005    if (ui8SliceType == IMG_FRAME_INTER_B)
2006    {
2007	ui8SliceType = IMG_FRAME_INTER_P;
2008	b8IsVopCoded = IMG_FALSE;
2009    } else {
2010	b8IsVopCoded = IMG_TRUE;
2011    }
2012
2013    eVop_Coding_Type = (ui8SliceType == IMG_FRAME_INTER_P) ? P_FRAME : I_FRAME;
2014
2015    psb_buffer_map(&(ps_mem->bufs_pic_template), &(ps_mem->bufs_pic_template.virtual_addr));
2016    if (ps_mem->bufs_pic_template.virtual_addr == NULL) {
2017        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping pic template\n", __FUNCTION__);
2018        return ;
2019    }
2020
2021    pPicHeaderMem = (MTX_HEADER_PARAMS *)((IMG_UINT8*)(ps_mem->bufs_pic_template.virtual_addr + (ctx->ctx_mem_size.pic_template * ui8OriginalSliceType)));
2022    //todo fix time resolution
2023    tng__MPEG4_notforsims_prepare_vop_header(pPicHeaderMem, b8IsVopCoded, ui8Search_range, eVop_Coding_Type);
2024    psb_buffer_unmap(&(ps_mem->bufs_pic_template));
2025
2026}
2027
2028void tng__h263_generate_pic_hdr_template(
2029    context_ENC_p ctx,
2030    IMG_FRAME_TEMPLATE_TYPE eFrameType,
2031    IMG_UINT16 ui16Width,
2032    IMG_UINT16 ui16Heigh)
2033
2034{
2035    context_ENC_mem *ps_mem = &(ctx->ctx_mem[ctx->ui32StreamID]);
2036    MTX_HEADER_PARAMS * pPicHeaderMem = NULL;
2037    H263_PICTURE_CODING_TYPE ePictureCodingType = ((eFrameType == IMG_FRAME_INTRA)|| (eFrameType == IMG_FRAME_IDR)) ? I_FRAME : P_FRAME;
2038
2039    psb_buffer_map(&(ps_mem->bufs_pic_template), &(ps_mem->bufs_pic_template.virtual_addr));
2040    if (ps_mem->bufs_pic_template.virtual_addr == NULL) {
2041        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping pic template\n", __FUNCTION__);
2042        return ;
2043    }
2044
2045    pPicHeaderMem = (MTX_HEADER_PARAMS *)((IMG_UINT8*)(ps_mem->bufs_pic_template.virtual_addr + (ctx->ctx_mem_size.pic_template * eFrameType)));
2046
2047    IMG_UINT8 ui8FrameRate = (IMG_UINT8)ctx->sRCParams.ui32FrameRate;
2048
2049    // Get a pointer to the memory the header will be written to
2050    tng__H263_notforsims_prepare_video_pictureheader(
2051        pPicHeaderMem,
2052        ePictureCodingType,
2053        ctx->ui8H263SourceFormat,
2054        ui8FrameRate,
2055        ui16Width,
2056        ui16Heigh);
2057
2058    psb_buffer_unmap(&(ps_mem->bufs_pic_template));
2059
2060}
2061
2062
2063static void tng__MPEG4ES_send_seq_header(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
2064{
2065    context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
2066    tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
2067
2068    psb_buffer_map(&(ps_mem->bufs_seq_header), &(ps_mem->bufs_seq_header.virtual_addr));
2069    if (ps_mem->bufs_seq_header.virtual_addr == NULL) {
2070        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping seq template\n", __FUNCTION__);
2071        return ;
2072    }
2073
2074    tng__MPEG4_prepare_sequence_header(ps_mem->bufs_seq_header.virtual_addr,
2075                                       IMG_FALSE,//FIXME: Zhaohan bFrame
2076                                       ctx->ui8ProfileIdc,//profile
2077                                       ctx->ui8LevelIdc,//ui8Profile_lvl_indication
2078                                       3,//ui8Fixed_vop_time_increment
2079                                       ctx->obj_context->picture_width,//ui8Fixed_vop_time_increment
2080                                       ctx->obj_context->picture_height,//ui32Picture_Height_Pixels
2081                                       NULL,//VBVPARAMS
2082                                       ctx->ui32VopTimeResolution);
2083    psb_buffer_unmap(&(ps_mem->bufs_seq_header));
2084
2085    cmdbuf->cmd_idx_saved[TNG_CMDBUF_SEQ_HEADER_IDX] = cmdbuf->cmd_idx;
2086}
2087
2088static void tng__H264ES_send_seq_header(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
2089{
2090    context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
2091    tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
2092    IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
2093    H264_VUI_PARAMS *psVuiParams = &(ctx->sVuiParams);
2094
2095//    memset(psVuiParams, 0, sizeof(H264_VUI_PARAMS));
2096
2097    if (psRCParams->eRCMode != IMG_RCMODE_NONE) {
2098        psVuiParams->vui_flag = 1;
2099        if (psVuiParams->num_units_in_tick == 0 || psVuiParams->Time_Scale == 0) {
2100            psVuiParams->num_units_in_tick = 1;
2101            psVuiParams->Time_Scale = psRCParams->ui32FrameRate * 2;
2102        }
2103        psVuiParams->bit_rate_value_minus1 = psRCParams->ui32BitsPerSecond / 64 - 1;
2104        psVuiParams->cbp_size_value_minus1 = psRCParams->ui32BufferSize / 64 - 1;
2105        psVuiParams->CBR = ((psRCParams->eRCMode == IMG_RCMODE_CBR) && (!psRCParams->bDisableBitStuffing)) ? 1 : 0;
2106        psVuiParams->initial_cpb_removal_delay_length_minus1 = BPH_SEI_NAL_INITIAL_CPB_REMOVAL_DELAY_SIZE - 1;
2107        psVuiParams->cpb_removal_delay_length_minus1 = PTH_SEI_NAL_CPB_REMOVAL_DELAY_SIZE - 1;
2108        psVuiParams->dpb_output_delay_length_minus1 = PTH_SEI_NAL_DPB_OUTPUT_DELAY_SIZE - 1;
2109        psVuiParams->time_offset_length = 24;
2110    }
2111    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s psVuiParams->vui_flag = %d\n", __FUNCTION__, psVuiParams->vui_flag);
2112
2113    psb_buffer_map(&(ps_mem->bufs_seq_header), &(ps_mem->bufs_seq_header.virtual_addr));
2114    if (ps_mem->bufs_seq_header.virtual_addr == NULL) {
2115        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping seq header\n", __FUNCTION__);
2116        return ;
2117    }
2118
2119    tng__H264ES_prepare_sequence_header(
2120        ps_mem->bufs_seq_header.virtual_addr,
2121        &(ctx->sVuiParams),
2122        &(ctx->sCropParams),
2123        ctx->ui16Width,         //ui8_picture_width_in_mbs
2124        ctx->ui16PictureHeight, //ui8_picture_height_in_mbs
2125        ctx->ui32CustomQuantMask,    //0,  ui8_custom_quant_mask
2126        ctx->ui8ProfileIdc,          //ui8_profile
2127        ctx->ui8LevelIdc,            //ui8_level
2128        ctx->ui8FieldCount,          //1,  ui8_field_count
2129        ctx->ui8MaxNumRefFrames,     //1,  ui8_max_num_ref_frames
2130        ctx->bPpsScaling,            //0   ui8_pps_scaling_cnt
2131        ctx->bUseDefaultScalingList, //0,  b_use_default_scaling_list
2132        ctx->bEnableLossless,        //0,  blossless
2133        ctx->bArbitrarySO
2134    );
2135    psb_buffer_unmap(&(ps_mem->bufs_seq_header));
2136
2137    if (ctx->bEnableMVC) {
2138        psb_buffer_map(&(ps_mem->bufs_sub_seq_header), &(ps_mem->bufs_sub_seq_header.virtual_addr));
2139        if (ps_mem->bufs_sub_seq_header.virtual_addr == NULL) {
2140            drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping sub seq header\n", __FUNCTION__);
2141            return ;
2142        }
2143        tng__H264ES_prepare_mvc_sequence_header(
2144            ps_mem->bufs_sub_seq_header.virtual_addr,
2145            &(ctx->sCropParams),
2146            ctx->ui16Width,         //ui8_picture_width_in_mbs
2147            ctx->ui16PictureHeight, //ui8_picture_height_in_mbs
2148            ctx->ui32CustomQuantMask,    //0,  ui8_custom_quant_mask
2149            ctx->ui8ProfileIdc,          //ui8_profile
2150            ctx->ui8LevelIdc,            //ui8_level
2151            ctx->ui8FieldCount,          //1,  ui8_field_count
2152            ctx->ui8MaxNumRefFrames,     //1,  ui8_max_num_ref_frames
2153            ctx->bPpsScaling,            //0   ui8_pps_scaling_cnt
2154            ctx->bUseDefaultScalingList, //0,  b_use_default_scaling_list
2155            ctx->bEnableLossless,        //0,  blossless
2156            ctx->bArbitrarySO
2157        );
2158        psb_buffer_unmap(&(ps_mem->bufs_sub_seq_header));
2159    }
2160
2161    cmdbuf->cmd_idx_saved[TNG_CMDBUF_SEQ_HEADER_IDX] = cmdbuf->cmd_idx;
2162
2163    return ;
2164}
2165
2166static void tng__H264ES_send_pic_header(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
2167{
2168    context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
2169    IMG_BOOL bDepViewPPS = IMG_FALSE;
2170
2171    if ((ctx->bEnableMVC) && (ctx->ui16MVCViewIdx != 0) &&
2172        (ctx->ui16MVCViewIdx != (IMG_UINT16)(NON_MVC_VIEW))) {
2173        bDepViewPPS = IMG_TRUE;
2174    }
2175
2176    psb_buffer_map(&(ps_mem->bufs_pic_template), &(ps_mem->bufs_pic_template.virtual_addr));
2177    if (ps_mem->bufs_pic_template.virtual_addr == NULL) {
2178        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping pic template\n", __FUNCTION__);
2179        return ;
2180    }
2181
2182    tng__H264ES_prepare_picture_header(
2183        ps_mem->bufs_pic_template.virtual_addr,
2184        ctx->bCabacEnabled,
2185        ctx->bH2648x8Transform,     //IMG_BOOL    b_8x8transform,
2186        ctx->bH264IntraConstrained, //IMG_BOOL    bIntraConstrained,
2187        0, //IMG_INT8    i8CQPOffset,
2188        0, //IMG_BOOL    bWeightedPrediction,
2189        0, //IMG_UINT8   ui8WeightedBiPred,
2190        bDepViewPPS, //IMG_BOOL    bMvcPPS,
2191        0, //IMG_BOOL    bScalingMatrix,
2192        0  //IMG_BOOL    bScalingLists
2193    );
2194
2195    psb_buffer_unmap(&(ps_mem->bufs_pic_template));
2196    return ;
2197}
2198
2199static void tng__H264ES_send_hrd_header(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
2200{
2201    unsigned int ui32nal_initial_cpb_removal_delay;
2202    unsigned int ui32nal_initial_cpb_removal_delay_offset;
2203    uint32_t ui32cpb_removal_delay;
2204    IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
2205    context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
2206    H264_VUI_PARAMS *psVuiParams = &(ctx->sVuiParams);
2207    IMG_UINT8 aui8clocktimestampflag[1];
2208    aui8clocktimestampflag[0] = IMG_FALSE;
2209
2210    ui32nal_initial_cpb_removal_delay =
2211        90000 * (1.0 * psRCParams->i32InitialDelay / psRCParams->ui32BitsPerSecond);
2212    ui32nal_initial_cpb_removal_delay_offset =
2213        90000 * (1.0 * ctx->buffer_size / psRCParams->ui32BitsPerSecond)
2214        - ui32nal_initial_cpb_removal_delay;
2215
2216    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert SEI buffer period message with "
2217            "ui32nal_initial_cpb_removal_delay(%d) and "
2218            "ui32nal_initial_cpb_removal_delay_offset(%d)\n",
2219            ui32nal_initial_cpb_removal_delay,
2220            ui32nal_initial_cpb_removal_delay_offset);
2221
2222    psb_buffer_map(&(ps_mem->bufs_sei_header), &(ps_mem->bufs_sei_header.virtual_addr));
2223    if (ps_mem->bufs_sei_header.virtual_addr == NULL) {
2224        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping sei header\n", __FUNCTION__);
2225        return ;
2226    }
2227
2228    if ((!ctx->bEnableMVC) || (ctx->ui16MVCViewIdx == 0)) {
2229        tng__H264ES_prepare_AUD_header(ps_mem->bufs_sei_header.virtual_addr);
2230    }
2231
2232    tng__H264ES_prepare_SEI_buffering_period_header(
2233        ps_mem->bufs_sei_header.virtual_addr + (ctx->ctx_mem_size.sei_header),
2234        0,// ui8cpb_cnt_minus1,
2235        psVuiParams->initial_cpb_removal_delay_length_minus1+1, //ui8initial_cpb_removal_delay_length,
2236        1, //ui8NalHrdBpPresentFlag,
2237        ui32nal_initial_cpb_removal_delay, // ui32nal_initial_cpb_removal_delay,
2238        ui32nal_initial_cpb_removal_delay_offset, //ui32nal_initial_cpb_removal_delay_offset,
2239        0, //ui8VclHrdBpPresentFlag - CURRENTLY HARD CODED TO ZERO IN TOPAZ
2240        NOT_USED_BY_TOPAZ, // ui32vcl_initial_cpb_removal_delay, (not used when ui8VclHrdBpPresentFlag = 0)
2241        NOT_USED_BY_TOPAZ); // ui32vcl_initial_cpb_removal_delay_offset (not used when ui8VclHrdBpPresentFlag = 0)
2242
2243    /* ui32cpb_removal_delay is zero for 1st frame and will be reset
2244     * after a IDR frame */
2245    if (ctx->ui32FrameCount[ui32StreamIndex] == 0) {
2246        if (ctx->ui32RawFrameCount == 0)
2247            ui32cpb_removal_delay = 0;
2248        else
2249            ui32cpb_removal_delay =
2250                ctx->ui32IdrPeriod * ctx->ui32IntraCnt * 2;
2251    } else
2252        ui32cpb_removal_delay = 2 * ctx->ui32FrameCount[ui32StreamIndex];
2253
2254    tng__H264ES_prepare_SEI_picture_timing_header(
2255        ps_mem->bufs_sei_header.virtual_addr + (ctx->ctx_mem_size.sei_header * 2),
2256        1, //ui8CpbDpbDelaysPresentFlag,
2257        psVuiParams->cpb_removal_delay_length_minus1, //cpb_removal_delay_length_minus1,
2258        psVuiParams->dpb_output_delay_length_minus1, //dpb_output_delay_length_minus1,
2259        ui32cpb_removal_delay, //ui32cpb_removal_delay,
2260        2, //ui32dpb_output_delay,
2261        0, //ui8pic_struct_present_flag (contained in the sequence header, Topaz hard-coded default to 0)
2262        NOT_USED_BY_TOPAZ, //ui8pic_struct, (not used when ui8pic_struct_present_flag = 0)
2263        NOT_USED_BY_TOPAZ, //NumClockTS, (not used when ui8pic_struct_present_flag = 0)
2264        aui8clocktimestampflag, //abclock_timestamp_flag, (not used when ui8pic_struct_present_flag = 0)
2265        NOT_USED_BY_TOPAZ, //ui8full_timestamp_flag, (not used when ui8pic_struct_present_flag = 0)
2266        NOT_USED_BY_TOPAZ, //ui8seconds_flag, (not used when ui8pic_struct_present_flag = 0)
2267        NOT_USED_BY_TOPAZ, //ui8minutes_flag, (not used when ui8pic_struct_present_flag = 0)
2268        NOT_USED_BY_TOPAZ, //ui8hours_flag, (not used when ui8pic_struct_present_flag = 0)
2269        NOT_USED_BY_TOPAZ, //seconds_value, (not used when ui8pic_struct_present_flag = 0)
2270        NOT_USED_BY_TOPAZ, //minutes_value, (not used when ui8pic_struct_present_flag = 0)
2271        NOT_USED_BY_TOPAZ, //hours_value, (not used when ui8pic_struct_present_flag = 0)
2272        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)
2273        NOT_USED_BY_TOPAZ, //nuit_field_based_flag, (not used when ui8pic_struct_present_flag = 0)
2274        NOT_USED_BY_TOPAZ, //counting_type (See TRM Table D 3 ?Definition of counting_type values)  (not used when ui8pic_struct_present_flag = 0)
2275        NOT_USED_BY_TOPAZ, //ui8discontinuity_flag, (not used when ui8pic_struct_present_flag = 0)
2276        NOT_USED_BY_TOPAZ, //ui8cnt_dropped_flag, (not used when ui8pic_struct_present_flag = 0)
2277        NOT_USED_BY_TOPAZ, //n_frames, (not used when ui8pic_struct_present_flag = 0)
2278        NOT_USED_BY_TOPAZ, //time_offset_length, (not used when ui8pic_struct_present_flag = 0)
2279        NOT_USED_BY_TOPAZ); //time_offset (not used when ui8pic_struct_present_flag = 0)
2280    psb_buffer_unmap(&(ps_mem->bufs_sei_header));
2281
2282    return ;
2283}
2284
2285static void tng__generate_slice_params_template(
2286    context_ENC_p ctx,
2287    IMG_UINT32 slice_buf_idx,
2288    IMG_UINT32 slice_type,
2289    IMG_UINT32 ui32StreamIndex
2290)
2291{
2292    context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
2293    IMG_UINT8  *slice_mem_temp_p = NULL;
2294    IMG_UINT32 ui32SliceHeight = 0;
2295    IMG_FRAME_TEMPLATE_TYPE slice_temp_type = (IMG_FRAME_TEMPLATE_TYPE)slice_type;
2296    IMG_FRAME_TEMPLATE_TYPE buf_idx = (IMG_FRAME_TEMPLATE_TYPE)slice_buf_idx;
2297
2298    if (ctx->ui8SlicesPerPicture != 0)
2299        ui32SliceHeight = ctx->ui16PictureHeight / ctx->ui8SlicesPerPicture;
2300    else
2301        drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s slice height\n", __FUNCTION__);
2302
2303    ui32SliceHeight &= ~15;
2304
2305    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG ui8DeblockIDC    = %x\n", __FUNCTION__, ctx->ui8DeblockIDC   );
2306    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG ui32SliceHeight  = %x\n", __FUNCTION__, ui32SliceHeight );
2307    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG bIsInterlaced    = %x\n", __FUNCTION__, ctx->bIsInterlaced   );
2308    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG iFineYSearchSize = %x\n", __FUNCTION__, ctx->iFineYSearchSize);
2309
2310    tng__prepare_encode_sliceparams(
2311        ctx,
2312        slice_buf_idx,
2313        slice_temp_type,
2314        0,                        // ui16CurrentRow,
2315        ui32SliceHeight,
2316        ctx->ui8DeblockIDC,       // uiDeblockIDC
2317        ctx->bIsInterlaced,       // bFieldMode
2318        ctx->iFineYSearchSize,
2319        ui32StreamIndex
2320    );
2321
2322    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG bCabacEnabled  = %x\n", __FUNCTION__, ctx->bCabacEnabled );
2323    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s PTG ui16MVCViewIdx = %x\n", __FUNCTION__, ctx->ui16MVCViewIdx);
2324
2325    if(ctx->bEnableMVC)
2326        ctx->ui16MVCViewIdx = (IMG_UINT16)ui32StreamIndex;
2327
2328    if (ps_mem->bufs_slice_template.virtual_addr == NULL) {
2329        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping slice template\n", __FUNCTION__);
2330        return ;
2331    }
2332
2333    slice_mem_temp_p = (IMG_UINT8*)(ps_mem->bufs_slice_template.virtual_addr + (ctx->ctx_mem_size.slice_template * buf_idx));
2334    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: addr 0x%08x, virtual 0x%08x, size = 0x%08x, buf_idx = %x\n",
2335        __FUNCTION__, slice_mem_temp_p, ps_mem->bufs_slice_template.virtual_addr, ctx->ctx_mem_size.slice_template, buf_idx);
2336
2337    /* Prepare Slice Header Template */
2338    switch (ctx->eStandard) {
2339    case IMG_STANDARD_NONE:
2340    case IMG_STANDARD_JPEG:
2341    case IMG_STANDARD_MPEG4:
2342        break;
2343    case IMG_STANDARD_H264:
2344        //H264_NOTFORSIMS_PrepareSliceHeader
2345        tng__H264ES_notforsims_prepare_sliceheader(
2346            slice_mem_temp_p,
2347            slice_temp_type,
2348            ctx->ui8DeblockIDC,
2349            0,                   // ui32FirstMBAddress
2350            0,                   // uiMBSkipRun
2351            ctx->bCabacEnabled,
2352            ctx->bIsInterlaced,
2353            ctx->ui16MVCViewIdx, //(IMG_UINT16)(NON_MVC_VIEW);
2354            IMG_FALSE            // bIsLongTermRef
2355        );
2356        break;
2357
2358    case IMG_STANDARD_H263:
2359        tng__H263ES_notforsims_prepare_gobsliceheader(slice_mem_temp_p);
2360        break;
2361
2362    case IMG_STANDARD_MPEG2:
2363        tng__MPEG2_prepare_sliceheader(slice_mem_temp_p);
2364        break;
2365    }
2366
2367    psb_buffer_unmap(&(ps_mem->bufs_slice_template));
2368
2369    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: end \n", __FUNCTION__);
2370
2371    return ;
2372}
2373
2374//H264_PrepareTemplates
2375static VAStatus tng__prepare_templates(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
2376{
2377    IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
2378    PIC_PARAMS *psPicParams = &(ctx->sPicParams);
2379    IN_RC_PARAMS* psInParams = &(psPicParams->sInParams);
2380    psPicParams->ui32Flags = 0;
2381
2382    tng__prepare_mv_estimates(ctx, ui32StreamIndex);
2383
2384    switch (ctx->eStandard) {
2385        case IMG_STANDARD_H263:
2386            psPicParams->ui32Flags |= ISH263_FLAGS;
2387            break;
2388        case IMG_STANDARD_MPEG4:
2389            psPicParams->ui32Flags |= ISMPEG4_FLAGS;
2390            break;
2391        case IMG_STANDARD_MPEG2:
2392            psPicParams->ui32Flags |= ISMPEG2_FLAGS;
2393            break;
2394        default:
2395            break;
2396    }
2397
2398    if (psRCParams->eRCMode) {
2399        psPicParams->ui32Flags |= ISRC_FLAGS;
2400        tng__setup_rcdata(ctx);
2401    } else {
2402        psInParams->ui8SeInitQP  = psRCParams->ui32InitialQp;
2403        psInParams->ui8MBPerRow  = (ctx->ui16Width >> 4);
2404        psInParams->ui16MBPerFrm = (ctx->ui16Width >> 4) * (ctx->ui16PictureHeight >> 4);
2405        psInParams->ui16MBPerBU  = psRCParams->ui32BUSize;
2406        psInParams->ui16BUPerFrm = (psInParams->ui16MBPerFrm) / psRCParams->ui32BUSize;
2407        ctx->ui32KickSize = psInParams->ui16MBPerBU;
2408    }
2409
2410    // Prepare Slice header templates
2411    tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_IDR, (IMG_UINT32)IMG_FRAME_IDR, ui32StreamIndex);
2412    tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_INTRA, (IMG_UINT32)IMG_FRAME_INTRA, ui32StreamIndex);
2413    tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_INTER_P, (IMG_UINT32)IMG_FRAME_INTER_P, ui32StreamIndex);
2414    switch(ctx->eStandard) {
2415	case IMG_STANDARD_H264:
2416	    tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_INTER_B, (IMG_UINT32)IMG_FRAME_INTER_B, ui32StreamIndex);
2417	    if (ctx->bEnableMVC)
2418		tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_INTER_P_IDR, (IMG_UINT32)IMG_FRAME_INTER_P_IDR, ui32StreamIndex);
2419            tng__H264ES_send_seq_header(ctx, 0);
2420            tng__H264ES_send_pic_header(ctx, 0);
2421            if (ctx->bInsertHRDParams)
2422                tng__H264ES_send_hrd_header(ctx, 0);
2423	    break;
2424	case IMG_STANDARD_H263:
2425	    tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_INTER_B, (IMG_UINT32)IMG_FRAME_INTER_B, ui32StreamIndex);
2426	    /* Here H263 uses the actual width and height */
2427	    tng__h263_generate_pic_hdr_template(ctx, IMG_FRAME_IDR, ctx->h263_actual_width, ctx->h263_actual_height);
2428            tng__h263_generate_pic_hdr_template(ctx, IMG_FRAME_INTRA, ctx->h263_actual_width, ctx->h263_actual_height);
2429            tng__h263_generate_pic_hdr_template(ctx, IMG_FRAME_INTER_P, ctx->h263_actual_width, ctx->h263_actual_height);
2430	    break;
2431	case IMG_STANDARD_MPEG4:
2432	    tng__generate_slice_params_template(ctx, (IMG_UINT32)IMG_FRAME_INTER_B, (IMG_UINT32)IMG_FRAME_INTER_P, ui32StreamIndex);
2433	    tng__mpeg4_generate_pic_hdr_template(ctx, IMG_FRAME_IDR, 4);
2434            tng__mpeg4_generate_pic_hdr_template(ctx, IMG_FRAME_INTRA, 4);
2435            tng__mpeg4_generate_pic_hdr_template(ctx, IMG_FRAME_INTER_P, 4);
2436	    tng__mpeg4_generate_pic_hdr_template(ctx, IMG_FRAME_INTER_B, 4);
2437	    break;
2438	default:
2439	    break;
2440    }
2441
2442    //FIXME: Zhaohan tng__mpeg2/mpeg4_generate_pic_hdr_template(IMG_FRAME_IDR\IMG_FRAME_INTRA\IMG_FRAME_INTER_P\IMG_FRAME_INTER_B);
2443
2444/*
2445    else {
2446        slice_mem_temp_p = (IMG_UINT8*)cmdbuf->slice_mem_p + (((IMG_UINT32)IMG_FRAME_INTER_P_IDR) * cmdbuf->mem_size);
2447        memset(slice_mem_temp_p, 0, 128);
2448    }
2449*/
2450    // Prepare Pic Params Templates
2451    tng__adjust_picflags(ctx, psRCParams, IMG_TRUE, &(ctx->ui32FirstPicFlags));
2452    tng__adjust_picflags(ctx, psRCParams, IMG_FALSE, &(ctx->ui32NonFirstPicFlags));
2453
2454    return VA_STATUS_SUCCESS;
2455}
2456
2457#if INPUT_SCALER_SUPPORTED
2458static IMG_FLOAT VIDEO_CalculateBessel0 (IMG_FLOAT fX)
2459{
2460    IMG_FLOAT fAX, fY;
2461
2462    fAX = (IMG_FLOAT)IMG_FABS(fX);
2463
2464    if (fAX < 3.75) 	{
2465        fY = (IMG_FLOAT)(fX / 3.75);
2466        fY *= fY;
2467
2468        return (IMG_FLOAT)(1.0 + fY *
2469            (3.5156229 + fY *
2470            (3.0899424 + fY *
2471            (1.2067492 + fY *
2472            (0.2659732 + fY *
2473            (0.360768e-1 + fY * 0.45813e-2))))));
2474    }
2475
2476    fY = (IMG_FLOAT)(3.75 / fAX);
2477
2478    return (IMG_FLOAT)((IMG_EXP(fAX) / IMG_SQRT(fAX)) *
2479        (0.39894228 + fY *
2480        (0.1328592e-1 + fY *
2481        (0.225319e-2 + fY *
2482        (-0.157565e-2 + fY *
2483        (0.916281e-2 + fY *
2484        (-0.2057706e-1 + fY *
2485        (0.2635537e-1 + fY *
2486        (-0.1647633e-1 + fY * 0.392377e-2)))))))));
2487}
2488
2489static IMG_FLOAT VIDEO_SincFunc (IMG_FLOAT fInput, IMG_FLOAT fScale)
2490{
2491    IMG_FLOAT fX;
2492    IMG_FLOAT fKaiser;
2493
2494    /* Kaiser window */
2495    fX = fInput / (4.0f / 2.0f) - 1.0f;
2496    fX = (IMG_FLOAT)IMG_SQRT(1.0f - fX * fX);
2497    fKaiser = VIDEO_CalculateBessel0(2.0f * fX) / VIDEO_CalculateBessel0(2.0f);
2498
2499    /* Sinc function */
2500    fX = 4.0f / 2.0f - fInput;
2501    if (fX == 0) {
2502        return fKaiser;
2503    }
2504
2505    fX *= 0.9f * fScale * 3.1415926535897f;
2506
2507    return fKaiser * (IMG_FLOAT)(IMG_SIN(fX) / fX);
2508}
2509
2510static void VIDEO_CalcCoefs_FromPitch (IMG_FLOAT	fPitch, IMG_UINT8 aui8Table[4][16])
2511{
2512    /* Based on sim code */
2513    /* The function is symmetrical, so we only need to calculate the first half of the taps, and the middle value. */
2514
2515    IMG_FLOAT	fScale;
2516    IMG_UINT32	ui32I, ui32Tap;
2517    IMG_FLOAT	afTable[4][16];
2518    IMG_INT32	i32Total;
2519    IMG_FLOAT	fTotal;
2520    IMG_INT32	i32MiddleTap, i32MiddleI;		/* Mirrored / middle Values for I and T */
2521
2522    if (fPitch < 1.0f) {
2523        fScale = 1.0f;
2524    } else {
2525        fScale = 1.0f / fPitch;
2526    }
2527
2528    for (ui32I = 0; ui32I < 16; ui32I++) {
2529        for (ui32Tap = 0; ui32Tap < 4; ui32Tap++) {
2530            afTable[ui32Tap][ui32I] = VIDEO_SincFunc(((IMG_FLOAT)ui32Tap) + ((IMG_FLOAT)ui32I) / 16.0f, fScale);
2531        }
2532    }
2533
2534    for (ui32Tap = 0; ui32Tap < 2; ui32Tap++) {
2535        for (ui32I = 0; ui32I < 16; ui32I++) {
2536            /* Copy the table around the centre point */
2537            i32MiddleTap = (3 - ui32Tap) + (16 - ui32I) / 16;
2538            i32MiddleI = (16 - ui32I) & 15;
2539            if ((IMG_UINT32)i32MiddleTap < 4) {
2540                afTable[i32MiddleTap][i32MiddleI] = afTable[ui32Tap][ui32I];
2541            }
2542        }
2543    }
2544
2545    /* The middle value */
2546    afTable[2][0] = VIDEO_SincFunc(2.0f, fScale);
2547
2548    /* Normalize this interpolation point, and convert to 2.6 format, truncating the result	*/
2549    for (ui32I = 0; ui32I < 16; ui32I++) {
2550        fTotal = 0.0f;
2551        i32Total = 0;
2552
2553        for (ui32Tap = 0; ui32Tap < 4; ui32Tap++) {
2554            fTotal += afTable[ui32Tap][ui32I];
2555        }
2556
2557        for (ui32Tap = 0; ui32Tap < 4; ui32Tap++) {
2558            aui8Table[ui32Tap][ui32I] = (IMG_UINT8)((afTable[ui32Tap][ui32I] * 64.0f) / fTotal);
2559            i32Total += aui8Table[ui32Tap][ui32I];
2560        }
2561
2562        if (ui32I <= 8) { /* normalize any floating point errors */
2563            i32Total -= 64;
2564            if (ui32I == 8) {
2565                i32Total /= 2;
2566            }
2567            /* Subtract the error from the I Point in the first tap ( this will not get
2568            mirrored, as it would go off the end). */
2569            aui8Table[0][ui32I] = (IMG_UINT8)(aui8Table[0][ui32I] - (IMG_UINT8)i32Total);
2570        }
2571    }
2572
2573    /* Copy the normalised table around the centre point */
2574    for (ui32Tap = 0; ui32Tap < 2; ui32Tap++) {
2575        for (ui32I = 0; ui32I < 16; ui32I++) {
2576            i32MiddleTap = (3 - ui32Tap) + (16 - ui32I) / 16;
2577            i32MiddleI = (16 - ui32I) & 15;
2578            if ((IMG_UINT32)i32MiddleTap < 4) {
2579                aui8Table[i32MiddleTap][i32MiddleI] = aui8Table[ui32Tap][ui32I];
2580            }
2581        }
2582    }
2583    return ;
2584}
2585#endif
2586
2587static void tng__setvideo_params(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
2588{
2589    context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
2590    context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
2591    IMG_MTX_VIDEO_CONTEXT* psMtxEncContext = NULL;
2592    IMG_RC_PARAMS * psRCParams = &(ctx->sRCParams);
2593    //IMG_UINT16 ui16WidthInMbs = (ctx->ui16Width + 15) >> 4;
2594    //IMG_UINT16 ui16FrameHeightInMbs = (ctx->ui16FrameHeight + 15) >> 4;
2595    IMG_INT nIndex;
2596    IMG_UINT8 ui8Flag;
2597#ifndef EXCLUDE_ADAPTIVE_ROUNDING
2598    IMG_INT32 i, j;
2599#endif
2600
2601    psb_buffer_map(&(ps_mem->bufs_mtx_context), &(ps_mem->bufs_mtx_context.virtual_addr));
2602    if (ps_mem->bufs_mtx_context.virtual_addr == NULL) {
2603        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping slice template\n", __FUNCTION__);
2604        return ;
2605    }
2606
2607    psMtxEncContext = (IMG_MTX_VIDEO_CONTEXT*)(ps_mem->bufs_mtx_context.virtual_addr);
2608
2609    ctx->i32PicNodes = (psRCParams->b16Hierarchical ? MAX_REF_B_LEVELS : 0) + ctx->ui8RefSpacing + 4;
2610    ctx->i32MVStores = (ctx->i32PicNodes * 2);
2611    ctx->ui8SlotsInUse = psRCParams->ui16BFrames + 2;
2612
2613    psMtxEncContext->ui32InitialQp = ctx->sRCParams.ui32InitialQp;
2614    psMtxEncContext->ui32BUSize = ctx->sRCParams.ui32BUSize;
2615    psMtxEncContext->ui16CQPOffset = (ctx->sRCParams.i8QCPOffset & 0x1f) | ((ctx->sRCParams.i8QCPOffset & 0x1f) << 8);
2616    psMtxEncContext->eStandard = ctx->eStandard;
2617    psMtxEncContext->ui32WidthInMbs = ctx->ui16Width >> 4;
2618    psMtxEncContext->ui32PictureHeightInMbs = ctx->ui16PictureHeight >> 4;
2619    psMtxEncContext->bOutputReconstructed = (ps_buf->rec_surface != NULL) ? IMG_TRUE : IMG_FALSE;
2620    psMtxEncContext->ui32VopTimeResolution = ctx->ui32VopTimeResolution;
2621    psMtxEncContext->ui8MaxSlicesPerPicture = ctx->ui8SlicesPerPicture;
2622    psMtxEncContext->ui8NumPipes = ctx->ui8PipesToUse;
2623    psMtxEncContext->eFormat = ctx->eFormat;
2624
2625    psMtxEncContext->b8IsInterlaced = ctx->bIsInterlaced;
2626    psMtxEncContext->b8TopFieldFirst = ctx->bTopFieldFirst;
2627    psMtxEncContext->b8ArbitrarySO = ctx->bArbitrarySO;
2628
2629    psMtxEncContext->ui32IdrPeriod = ctx->ui32IdrPeriod * ctx->ui32IntraCnt;
2630    psMtxEncContext->ui32BFrameCount = ctx->sRCParams.ui16BFrames;
2631    psMtxEncContext->b8Hierarchical = (IMG_BOOL8) ctx->sRCParams.b16Hierarchical;
2632    psMtxEncContext->ui32IntraLoopCnt = ctx->ui32IntraCnt;
2633    psMtxEncContext->ui8RefSpacing = ctx->ui8RefSpacing;
2634    psMtxEncContext->ui32DebugCRCs = ctx->ui32DebugCRCs;
2635
2636    psMtxEncContext->ui8FirstPipe = ctx->ui8BasePipe;
2637    psMtxEncContext->ui8LastPipe = ctx->ui8BasePipe + ctx->ui8PipesToUse - 1;
2638    psMtxEncContext->ui8PipesToUseFlags = 0;
2639    ui8Flag = 0x1 << psMtxEncContext->ui8FirstPipe;
2640    for (nIndex = 0; nIndex < psMtxEncContext->ui8NumPipes; nIndex++, ui8Flag<<=1)
2641        psMtxEncContext->ui8PipesToUseFlags |= ui8Flag; //Pipes used MUST be contiguous from the BasePipe offset
2642
2643    // Only used in MPEG2, 2 bit field (0 = 8 bit, 1 = 9 bit, 2 = 10 bit and 3=11 bit precision)
2644    if (ctx->eStandard == IMG_STANDARD_MPEG2)
2645        psMtxEncContext->ui8MPEG2IntraDCPrecision = ctx->ui8MPEG2IntraDCPrecision;
2646
2647    psMtxEncContext->b16EnableMvc = ctx->bEnableMVC;
2648    psMtxEncContext->ui16MvcViewIdx = ctx->ui16MVCViewIdx;
2649    if (ctx->eStandard == IMG_STANDARD_H264)
2650        psMtxEncContext->b16NoSequenceHeaders = ctx->bNoSequenceHeaders;
2651
2652    {
2653        IMG_UINT16 ui16SrcYStride = 0, ui16SrcUVStride = 0;
2654        // 3 Components: Y, U, V
2655        ctx->ui16BufferStride = ps_buf->src_surface->psb_surface->stride;
2656        ui16SrcUVStride = ui16SrcYStride = ctx->ui16BufferStride;
2657        ctx->ui16BufferHeight = ctx->ui16FrameHeight;
2658        switch (ctx->eFormat) {
2659        case IMG_CODEC_YUV:
2660        case IMG_CODEC_PL8:
2661        case IMG_CODEC_YV12:
2662            ui16SrcUVStride = ui16SrcYStride / 2;
2663            break;
2664
2665        case IMG_CODEC_PL12:            // Interleaved chroma pixels
2666        case IMG_CODEC_IMC2:            // Interleaved chroma rows
2667        case IMG_CODEC_422_YUV:         // Odd-numbered chroma rows unused
2668        case IMG_CODEC_422_YV12:        // Odd-numbered chroma rows unused
2669        case IMG_CODEC_422_PL8:         // Odd-numbered chroma rows unused
2670        case IMG_CODEC_Y0UY1V_8888: // Interleaved luma and chroma pixels
2671        case IMG_CODEC_Y0VY1U_8888: // Interleaved luma and chroma pixels
2672        case IMG_CODEC_UY0VY1_8888: // Interleaved luma and chroma pixels
2673        case IMG_CODEC_VY0UY1_8888: // Interleaved luma and chroma pixels
2674            ui16SrcUVStride = ui16SrcYStride;
2675            break;
2676
2677        case IMG_CODEC_422_IMC2:        // Interleaved chroma pixels and unused odd-numbered chroma rows
2678        case IMG_CODEC_422_PL12:        // Interleaved chroma rows and unused odd-numbered chroma rows
2679            ui16SrcUVStride = ui16SrcYStride * 2;
2680            break;
2681
2682        default:
2683            break;
2684        }
2685
2686        if ((ctx->bIsInterlaced) && (ctx->bIsInterleaved)) {
2687            ui16SrcYStride *= 2;                    // ui16SrcYStride
2688            ui16SrcUVStride *= 2;           // ui16SrcUStride
2689        }
2690
2691        psMtxEncContext->ui32PicRowStride = F_ENCODE(ui16SrcYStride >> 6, TOPAZHP_CR_CUR_PIC_LUMA_STRIDE) |
2692                                            F_ENCODE(ui16SrcUVStride >> 6, TOPAZHP_CR_CUR_PIC_CHROMA_STRIDE);
2693    }
2694
2695    psMtxEncContext->eRCMode = ctx->sRCParams.eRCMode;
2696    psMtxEncContext->b8DisableBitStuffing = ctx->sRCParams.bDisableBitStuffing;
2697    psMtxEncContext->b8FirstPic = IMG_TRUE;
2698
2699    /*Contents Adaptive Rate Control Parameters*/
2700    psMtxEncContext->bCARC          =  ctx->sCARCParams.bCARC;
2701    psMtxEncContext->iCARCBaseline  =  ctx->sCARCParams.i32CARCBaseline;
2702    psMtxEncContext->uCARCThreshold =  ctx->sCARCParams.ui32CARCThreshold;
2703    psMtxEncContext->uCARCCutoff    =  ctx->sCARCParams.ui32CARCCutoff;
2704    psMtxEncContext->uCARCNegRange  =  ctx->sCARCParams.ui32CARCNegRange;
2705    psMtxEncContext->uCARCNegScale  =  ctx->sCARCParams.ui32CARCNegScale;
2706    psMtxEncContext->uCARCPosRange  =  ctx->sCARCParams.ui32CARCPosRange;
2707    psMtxEncContext->uCARCPosScale  =  ctx->sCARCParams.ui32CARCPosScale;
2708    psMtxEncContext->uCARCShift     =  ctx->sCARCParams.ui32CARCShift;
2709    psMtxEncContext->ui32MVClip_Config =  F_ENCODE(ctx->bNoOffscreenMv, TOPAZHP_CR_MVCALC_RESTRICT_PICTURE);
2710    psMtxEncContext->ui32LRITC_Tile_Use_Config = 0;
2711    psMtxEncContext->ui32LRITC_Cache_Chunk_Config = 0;
2712
2713    psMtxEncContext->ui32IPCM_0_Config = F_ENCODE(ctx->ui32CabacBinFlex, TOPAZ_VLC_CR_CABAC_BIN_FLEX) |
2714        F_ENCODE(DEFAULT_CABAC_DB_MARGIN, TOPAZ_VLC_CR_CABAC_DB_MARGIN);
2715
2716    psMtxEncContext->ui32IPCM_1_Config = F_ENCODE(3200, TOPAZ_VLC_CR_IPCM_THRESHOLD) |
2717        F_ENCODE(ctx->ui32CabacBinLimit, TOPAZ_VLC_CR_CABAC_BIN_LIMIT);
2718
2719    // leave alone until high profile and constrained modes are defined.
2720    psMtxEncContext->ui32H264CompControl  = F_ENCODE((ctx->bCabacEnabled ? 0 : 1), TOPAZHP_CR_H264COMP_8X8_CAVLC);
2721
2722    psMtxEncContext->ui32H264CompControl |= F_ENCODE(ctx->bUseDefaultScalingList ? 1 : 0, TOPAZHP_CR_H264COMP_DEFAULT_SCALING_LIST);
2723
2724    psMtxEncContext->ui32H264CompControl |= F_ENCODE(ctx->bH2648x8Transform ? 1 : 0, TOPAZHP_CR_H264COMP_8X8_TRANSFORM);
2725
2726    psMtxEncContext->ui32H264CompControl |= F_ENCODE(ctx->bH264IntraConstrained ? 1 : 0, TOPAZHP_CR_H264COMP_CONSTRAINED_INTRA);
2727
2728
2729#ifndef EXCLUDE_ADAPTIVE_ROUNDING
2730    psMtxEncContext->bMCAdaptiveRoundingDisable = ctx->bVPAdaptiveRoundingDisable;
2731    psMtxEncContext->ui32H264CompControl |= F_ENCODE(psMtxEncContext->bMCAdaptiveRoundingDisable ? 0 : 1, TOPAZHP_CR_H264COMP_ADAPT_ROUND_ENABLE);
2732
2733    if (!psMtxEncContext->bMCAdaptiveRoundingDisable)
2734        for (i = 0; i < 4; i++)
2735            for (j = 0; j < 18; j++)
2736                psMtxEncContext->ui16MCAdaptiveRoundingOffsets[j][i] = H264_ROUNDING_OFFSETS[j][i];
2737#endif
2738
2739    if ((ctx->eStandard == IMG_STANDARD_H264) && (ctx->ui32CoreRev >= MIN_34_REV)) {
2740        psMtxEncContext->ui32H264CompControl |= F_ENCODE(USE_VCM_HW_SUPPORT, TOPAZHP_CR_H264COMP_VIDEO_CONF_ENABLE);
2741    }
2742
2743    psMtxEncContext->ui32H264CompControl |=
2744           F_ENCODE(ctx->ui16UseCustomScalingLists & 0x01 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_4X4_INTRA_LUMA_ENABLE)
2745        | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x02 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_4X4_INTRA_CB_ENABLE)
2746        | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x04 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_4X4_INTRA_CR_ENABLE)
2747        | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x08 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_4X4_INTER_LUMA_ENABLE)
2748        | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x10 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_4X4_INTER_CB_ENABLE)
2749        | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x20 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_4X4_INTER_CR_ENABLE)
2750        | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x40 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_8X8_INTRA_LUMA_ENABLE)
2751        | F_ENCODE(ctx->ui16UseCustomScalingLists & 0x80 ? 1 : 0, TOPAZHP_CR_H264COMP_CUSTOM_QUANT_8X8_INTER_LUMA_ENABLE);
2752
2753    psMtxEncContext->ui32H264CompControl |=
2754           F_ENCODE(ctx->bEnableLossless ? 1 : 0, INTEL_H264_LL)
2755        | F_ENCODE(ctx->bLossless8x8Prefilter ? 1 : 0, INTEL_H264_LL8X8P);
2756
2757    psMtxEncContext->ui32H264CompIntraPredModes = 0x3ffff;// leave at default for now.
2758    psMtxEncContext->ui32PredCombControl = ctx->ui32PredCombControl;
2759    psMtxEncContext->ui32SkipCodedInterIntra = F_ENCODE(ctx->ui8InterIntraIndex, TOPAZHP_CR_INTER_INTRA_SCALE_IDX)
2760        |F_ENCODE(ctx->ui8CodedSkippedIndex, TOPAZHP_CR_SKIPPED_CODED_SCALE_IDX);
2761
2762    if (ctx->bEnableInpCtrl) {
2763        psMtxEncContext->ui32MBHostCtrl = F_ENCODE(ctx->bEnableHostQP, TOPAZHP_CR_MB_HOST_QP)
2764            |F_ENCODE(ctx->bEnableHostBias, TOPAZHP_CR_MB_HOST_SKIPPED_CODED_SCALE)
2765            |F_ENCODE(ctx->bEnableHostBias, TOPAZHP_CR_MB_HOST_INTER_INTRA_SCALE);
2766        psMtxEncContext->ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTER_INTRA_SCALE_ENABLE)
2767            |F_ENCODE(1, TOPAZHP_CR_SKIPPED_CODED_SCALE_ENABLE);
2768    }
2769
2770    if (ctx->bEnableCumulativeBiases)
2771        psMtxEncContext->ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_CUMULATIVE_BIASES_ENABLE);
2772
2773    psMtxEncContext->ui32PredCombControl |=
2774        F_ENCODE((((ctx->ui8InterIntraIndex == 3) && (ctx->ui8CodedSkippedIndex == 3)) ? 0 : 1), TOPAZHP_CR_INTER_INTRA_SCALE_ENABLE) |
2775        F_ENCODE((ctx->ui8CodedSkippedIndex == 3 ? 0 : 1), TOPAZHP_CR_SKIPPED_CODED_SCALE_ENABLE);
2776    // 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.
2777    //      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);
2778    //psMtxEncContext->ui32PredCombControl |= F_ENCODE(1, TOPAZHP_CR_INTER_INTRA_SCALE_ENABLE) | F_ENCODE(1, TOPAZHP_CR_SKIPPED_CODED_SCALE_ENABLE);
2779    psMtxEncContext->ui32DeblockCtrl = F_ENCODE(ctx->ui8DeblockIDC, TOPAZ_DB_CR_DISABLE_DEBLOCK_IDC);
2780    psMtxEncContext->ui32VLCControl = 0;
2781
2782    switch (ctx->eStandard) {
2783    case IMG_STANDARD_H264:
2784        psMtxEncContext->ui32VLCControl |= F_ENCODE(1, TOPAZ_VLC_CR_CODEC); // 1 for H.264 note this is inconsistant with the sequencer value
2785        psMtxEncContext->ui32VLCControl |= F_ENCODE(0, TOPAZ_VLC_CR_CODEC_EXTEND);
2786
2787        break;
2788    case IMG_STANDARD_H263:
2789        psMtxEncContext->ui32VLCControl |= F_ENCODE(3, TOPAZ_VLC_CR_CODEC); // 3 for H.263 note this is inconsistant with the sequencer value
2790        psMtxEncContext->ui32VLCControl |= F_ENCODE(0, TOPAZ_VLC_CR_CODEC_EXTEND);
2791
2792        break;
2793    case IMG_STANDARD_MPEG4:
2794        psMtxEncContext->ui32VLCControl |= F_ENCODE(2, TOPAZ_VLC_CR_CODEC); // 2 for Mpeg4 note this is inconsistant with the sequencer value
2795        psMtxEncContext->ui32VLCControl |= F_ENCODE(0, TOPAZ_VLC_CR_CODEC_EXTEND);
2796        break;
2797    case IMG_STANDARD_MPEG2:
2798        psMtxEncContext->ui32VLCControl |= F_ENCODE(0, TOPAZ_VLC_CR_CODEC);
2799        psMtxEncContext->ui32VLCControl |= F_ENCODE(1, TOPAZ_VLC_CR_CODEC_EXTEND);
2800        break;
2801    default:
2802        break;
2803    }
2804
2805    if (ctx->bCabacEnabled) {
2806        psMtxEncContext->ui32VLCControl |= F_ENCODE(1, TOPAZ_VLC_CR_CABAC_ENABLE); // 2 for Mpeg4 note this is inconsistant with the sequencer value
2807    }
2808
2809    psMtxEncContext->ui32VLCControl |= F_ENCODE(ctx->bIsInterlaced ? 1 : 0, TOPAZ_VLC_CR_VLC_FIELD_CODED);
2810    psMtxEncContext->ui32VLCControl |= F_ENCODE(ctx->bH2648x8Transform ? 1 : 0, TOPAZ_VLC_CR_VLC_8X8_TRANSFORM);
2811    psMtxEncContext->ui32VLCControl |= F_ENCODE(ctx->bH264IntraConstrained ? 1 : 0, TOPAZ_VLC_CR_VLC_CONSTRAINED_INTRA);
2812
2813    psMtxEncContext->ui32VLCSliceControl = F_ENCODE(ctx->sRCParams.ui32SliceByteLimit, TOPAZ_VLC_CR_SLICE_SIZE_LIMIT);
2814    psMtxEncContext->ui32VLCSliceMBControl = F_ENCODE(ctx->sRCParams.ui32SliceMBLimit, TOPAZ_VLC_CR_SLICE_MBS_LIMIT);
2815
2816        switch (ctx->eStandard) {
2817            case IMG_STANDARD_H264: {
2818                IMG_UINT32 ui32VertMVLimit = 255; // default to no clipping
2819                if (ctx->ui32VertMVLimit)
2820                    ui32VertMVLimit = ctx->ui32VertMVLimit;
2821                // as topaz can only cope with at most 255 (in the register field)
2822                ui32VertMVLimit = tng__min(255,ui32VertMVLimit);
2823                // workaround for BRN 29973 and 30032
2824                {
2825#if defined(BRN_29973) || defined(BRN_30032)
2826                    if (ctx->ui32CoreRev <= 0x30006) {
2827                        if ((ctx->ui16Width / 16) & 1) // BRN 30032, if odd number of macroblocks we need to limit vector to +-112
2828                            psMtxEncContext->ui32IPEVectorClipping = F_ENCODE(1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_ENABLED)
2829                                |F_ENCODE(112, TOPAZHP_CR_IPE_VECTOR_CLIPPING_X)
2830                                |F_ENCODE(ui32VertMVLimit, TOPAZHP_CR_IPE_VECTOR_CLIPPING_Y);
2831                        else // for 29973 we need to limit vector to +-120
2832                            if (ctx->ui16Width >= 1920)
2833                                psMtxEncContext->ui32IPEVectorClipping = F_ENCODE(1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_ENABLED)
2834                                |F_ENCODE(120, TOPAZHP_CR_IPE_VECTOR_CLIPPING_X)
2835                                |F_ENCODE(ui32VertMVLimit, TOPAZHP_CR_IPE_VECTOR_CLIPPING_Y);
2836                            else
2837                                psMtxEncContext->ui32IPEVectorClipping = F_ENCODE(1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_ENABLED)
2838                                |F_ENCODE(255, TOPAZHP_CR_IPE_VECTOR_CLIPPING_X)
2839                                |F_ENCODE(ui32VertMVLimit, TOPAZHP_CR_IPE_VECTOR_CLIPPING_Y);
2840                    } else
2841#endif
2842                        {
2843                            psMtxEncContext->ui32IPEVectorClipping =
2844                            F_ENCODE(1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_ENABLED) |
2845                            F_ENCODE(255, TOPAZHP_CR_IPE_VECTOR_CLIPPING_X) |
2846                            F_ENCODE(ui32VertMVLimit, TOPAZHP_CR_IPE_VECTOR_CLIPPING_Y);
2847                        }
2848                    }
2849                    psMtxEncContext->ui32SPEMvdClipRange = F_ENCODE(0, TOPAZHP_CR_SPE_MVD_CLIP_ENABLE);
2850            }
2851            break;
2852            case IMG_STANDARD_H263:
2853                {
2854                    psMtxEncContext->ui32IPEVectorClipping = F_ENCODE(1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_ENABLED)
2855                        | F_ENCODE(16 - 1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_X)
2856                        | F_ENCODE(16 - 1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_Y);
2857
2858                    psMtxEncContext->ui32SPEMvdClipRange = F_ENCODE(1, TOPAZHP_CR_SPE_MVD_CLIP_ENABLE)
2859                        | F_ENCODE( 62, TOPAZHP_CR_SPE_MVD_POS_CLIP)
2860                        | F_ENCODE(-64, TOPAZHP_CR_SPE_MVD_NEG_CLIP);
2861                }
2862                break;
2863            case IMG_STANDARD_MPEG4:
2864            case IMG_STANDARD_MPEG2:
2865                {
2866                    IMG_UINT8 uX, uY, uResidualSize;
2867                    //The maximum MPEG4 and MPEG2 motion vector differential in 1/2 pixels is
2868                    //calculated as 1 << (fcode - 1) * 32 or *16 in MPEG2
2869
2870                    uResidualSize=(ctx->eStandard == IMG_STANDARD_MPEG4 ? 32 : 16);
2871
2872                    uX = tng__min(128 - 1, (((1<<(ctx->sBiasTables.ui32FCode - 1)) * uResidualSize)/4) - 1);
2873                    uY = tng__min(104 - 1, (((1<<(ctx->sBiasTables.ui32FCode - 1)) * uResidualSize)/4) - 1);
2874
2875                    //Write to register
2876                    psMtxEncContext->ui32IPEVectorClipping = F_ENCODE(1, TOPAZHP_CR_IPE_VECTOR_CLIPPING_ENABLED)
2877                        | F_ENCODE(uX, TOPAZHP_CR_IPE_VECTOR_CLIPPING_X)
2878                        | F_ENCODE(uY, TOPAZHP_CR_IPE_VECTOR_CLIPPING_Y);
2879
2880                    psMtxEncContext->ui32SPEMvdClipRange = F_ENCODE(0, TOPAZHP_CR_SPE_MVD_CLIP_ENABLE);
2881                }
2882                break;
2883            case IMG_STANDARD_JPEG:
2884			case IMG_STANDARD_NONE:
2885			default:
2886			    break;
2887        }
2888#ifdef FIRMWARE_BIAS
2889    //copy the bias tables
2890    {
2891        int n;
2892        for (n = 52; n >= 0; n -= 2)    {
2893            psMtxEncContext->aui32DirectBias_P[n >> 1] = ctx->sBiasTables.aui32DirectBias_P[n];
2894            psMtxEncContext->aui32InterBias_P[n >> 1] = ctx->sBiasTables.aui32InterBias_P[n];
2895            psMtxEncContext->aui32DirectBias_B[n >> 1] = ctx->sBiasTables.aui32DirectBias_B[n];
2896            psMtxEncContext->aui32InterBias_B[n >> 1] = ctx->sBiasTables.aui32InterBias_B[n];
2897        }
2898    }
2899#endif
2900
2901    //copy the scale-tables
2902    tng__generate_scale_tables(psMtxEncContext);
2903//      memcpy(psMtxEncContext->ui32InterIntraScale, ctx->ui32InterIntraScale, sizeof(IMG_UINT32)*SCALE_TBL_SZ);
2904//      memcpy(psMtxEncContext->ui32SkippedCodedScale, ctx->ui32SkippedCodedScale, sizeof(IMG_UINT32)*SCALE_TBL_SZ);
2905
2906    // WEIGHTED PREDICTION
2907    psMtxEncContext->b8WeightedPredictionEnabled = ctx->bWeightedPrediction;
2908    psMtxEncContext->ui8MTXWeightedImplicitBiPred = ctx->ui8VPWeightedImplicitBiPred;
2909
2910    // SEI_INSERTION
2911    psMtxEncContext->b8InsertHRDparams = ctx->bInsertHRDParams;
2912    if (psMtxEncContext->b8InsertHRDparams & !ctx->sRCParams.ui32BitsPerSecond) {   //ctx->uBitRate
2913        /* HRD parameters are meaningless without a bitrate */
2914        psMtxEncContext->b8InsertHRDparams = IMG_FALSE;
2915    }
2916    if (psMtxEncContext->b8InsertHRDparams) {
2917        psMtxEncContext->ui64ClockDivBitrate = (90000 * 0x100000000LL);
2918        psMtxEncContext->ui64ClockDivBitrate /= ctx->sRCParams.ui32BitsPerSecond;                       //ctx->uBitRate;
2919        psMtxEncContext->ui32MaxBufferMultClockDivBitrate = (IMG_UINT32)(((IMG_UINT64)(ctx->sRCParams.ui32BufferSize) *
2920                (IMG_UINT64) 90000) / (IMG_UINT64) ctx->sRCParams.ui32BitsPerSecond);
2921    }
2922
2923    memcpy(&psMtxEncContext->sInParams, &ctx->sPicParams.sInParams, sizeof(IN_RC_PARAMS));
2924    // Update MV Scaling settings
2925    // IDR
2926    //      memcpy(&psMtxEncContext->sMVSettingsIdr, &ctx->sMVSettingsIdr, sizeof(IMG_MV_SETTINGS));
2927    // NonB (I or P)
2928    //      for (i = 0; i <= MAX_BFRAMES; i++)
2929    //              memcpy(&psMtxEncContext->sMVSettingsNonB[i], &ctx->sMVSettingsNonB[i], sizeof(IMG_MV_SETTINGS));
2930
2931    psMtxEncContext->ui32LRITC_Cache_Chunk_Config =
2932        F_ENCODE(ctx->uChunksPerMb, INTEL_CH_PM) |
2933        F_ENCODE(ctx->uMaxChunks, INTEL_CH_MX) |
2934        F_ENCODE(ctx->uMaxChunks - ctx->uPriorityChunks, INTEL_CH_PY);
2935
2936
2937    //they would be set in function tng__prepare_templates()
2938    psMtxEncContext->ui32FirstPicFlags = ctx->ui32FirstPicFlags;
2939    psMtxEncContext->ui32NonFirstPicFlags = ctx->ui32NonFirstPicFlags;
2940
2941#ifdef LTREFHEADER
2942    psMtxEncContext->i8SliceHeaderSlotNum = -1;
2943#endif
2944
2945    {
2946        memset(psMtxEncContext->aui8PicOnLevel, 0, sizeof(psMtxEncContext->aui8PicOnLevel));
2947        psb_buffer_map(&(ps_mem->bufs_flat_gop), &(ps_mem->bufs_flat_gop.virtual_addr));
2948        if (ps_mem->bufs_flat_gop.virtual_addr == NULL) {
2949           drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping flat gop\n", __FUNCTION__);
2950           return ;
2951        }
2952        tng__minigop_generate_flat(ps_mem->bufs_flat_gop.virtual_addr, psMtxEncContext->ui32BFrameCount,
2953            psMtxEncContext->ui8RefSpacing, psMtxEncContext->aui8PicOnLevel);
2954        psb_buffer_unmap(&(ps_mem->bufs_flat_gop));
2955
2956        if (ctx->sRCParams.b16Hierarchical) {
2957            memset(psMtxEncContext->aui8PicOnLevel, 0, sizeof(psMtxEncContext->aui8PicOnLevel));
2958            psb_buffer_map(&(ps_mem->bufs_hierar_gop), &(ps_mem->bufs_hierar_gop.virtual_addr));
2959            if (ps_mem->bufs_hierar_gop.virtual_addr == NULL) {
2960                drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping sei header\n", __FUNCTION__);
2961                return ;
2962            }
2963            tng_minigop_generate_hierarchical(ps_mem->bufs_hierar_gop.virtual_addr, psMtxEncContext->ui32BFrameCount,
2964                psMtxEncContext->ui8RefSpacing, psMtxEncContext->aui8PicOnLevel);
2965            psb_buffer_unmap(&(ps_mem->bufs_hierar_gop));
2966        }
2967    }
2968
2969#if INPUT_SCALER_SUPPORTED
2970    if (ctx->bEnableScaler) {
2971        IMG_UINT8 sccCoeffs[4][16];
2972        IMG_UINT32 ui32PitchX, ui32PitchY;
2973        IMG_INT32 i32Phase, i32Tap;
2974
2975        ui32PitchX = (((IMG_UINT32)(psVideoParams->ui16SourceWidth - psVideoParams->ui8CropLeft - psVideoParams->ui8CropRight)) << 12) / psVideoParams->ui16Width;
2976        ui32PitchY = (((IMG_UINT32)(psVideoParams->ui16SourceFrameHeight - psVideoParams->ui8CropTop - psVideoParams->ui8CropBottom)) << 12) / psVideoParams->ui16FrameHeight;
2977
2978        // Input size
2979        psMtxEncContext->ui32ScalerInputSizeReg = F_ENCODE(psVideoParams->ui16SourceWidth - 1, TOPAZHP_EXT_CR_SCALER_INPUT_WIDTH_MIN1) |
2980            F_ENCODE((psVideoParams->ui16SourceFrameHeight >> (psVideo->bIsInterlaced ? 1 : 0)) - 1, TOPAZHP_EXT_CR_SCALER_INPUT_HEIGHT_MIN1);
2981
2982        psMtxEncContext->ui32ScalerCropReg = F_ENCODE(psVideoParams->ui8CropLeft, TOPAZHP_EXT_CR_SCALER_INPUT_CROP_HOR) |
2983            F_ENCODE(psVideoParams->ui8CropTop, TOPAZHP_EXT_CR_SCALER_INPUT_CROP_VER);
2984
2985        // Scale factors
2986        psMtxEncContext->ui32ScalerPitchReg = 0;
2987
2988        if (ui32PitchX > 0x3FFF) {
2989            psMtxEncContext->ui32ScalerPitchReg |= F_ENCODE(1, TOPAZHP_EXT_CR_SCALER_HOR_BILINEAR_FILTER);
2990            ui32PitchX >>= 1;
2991        }
2992
2993        if (ui32PitchX > 0x3FFF) {
2994            ui32PitchX = 0x3FFF;
2995        }
2996
2997        if (ui32PitchY > 0x3FFF) {
2998            psMtxEncContext->ui32ScalerPitchReg |= F_ENCODE(1, TOPAZHP_EXT_CR_SCALER_VER_BILINEAR_FILTER);
2999            ui32PitchY >>= 1;
3000        }
3001
3002        if (ui32PitchY > 0x3FFF) {
3003            ui32PitchY = 0x3FFF;
3004        }
3005
3006        psMtxEncContext->ui32ScalerPitchReg |= F_ENCODE(ui32PitchX, TOPAZHP_EXT_CR_SCALER_INPUT_HOR_PITCH) |
3007            F_ENCODE(ui32PitchY, TOPAZHP_EXT_CR_SCALER_INPUT_VER_PITCH);
3008
3009
3010        // Coefficients
3011        VIDEO_CalcCoefs_FromPitch(((IMG_FLOAT)ui32PitchX) / 4096.0f, sccCoeffs);
3012
3013        for (i32Phase = 0; i32Phase < 4; i32Phase++) {
3014            psMtxEncContext->asHorScalerCoeffRegs[i32Phase] = 0;
3015            for (i32Tap = 0; i32Tap < 4; i32Tap++) 	{
3016                psMtxEncContext->asHorScalerCoeffRegs[i32Phase] |= F_ENCODE(sccCoeffs[3 - i32Tap][(i32Phase * 2) + 1], TOPAZHP_EXT_CR_SCALER_HOR_LUMA_COEFF(i32Tap));
3017            }
3018        }
3019
3020        VIDEO_CalcCoefs_FromPitch(((IMG_FLOAT)ui32PitchY) / 4096.0f, sccCoeffs);
3021
3022        for (i32Phase = 0; i32Phase < 4; i32Phase++) {
3023            psMtxEncContext->asVerScalerCoeffRegs[i32Phase] = 0;
3024            for (i32Tap = 0; i32Tap < 4; i32Tap++) {
3025                psMtxEncContext->asVerScalerCoeffRegs[i32Phase] |= F_ENCODE(sccCoeffs[3 - i32Tap][(i32Phase * 2) + 1], TOPAZHP_EXT_CR_SCALER_VER_LUMA_COEFF(i32Tap));
3026            }
3027        }
3028    } else {
3029        // Disable scaling
3030        psMtxEncContext->ui32ScalerInputSizeReg = 0;
3031    }
3032#endif // INPUT_SCALER_SUPPORTED
3033
3034    psb_buffer_unmap(&(ps_mem->bufs_mtx_context));
3035
3036    return ;
3037}
3038
3039static void tng__setvideo_cmdbuf(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
3040{
3041    context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
3042    context_ENC_mem_size *ps_mem_size = &(ctx->ctx_mem_size);
3043#ifndef _TNG_FRAMES_
3044    context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
3045#endif
3046    IMG_MTX_VIDEO_CONTEXT* psMtxEncContext = NULL;
3047    IMG_INT32 i;
3048
3049    psb_buffer_map(&(ps_mem->bufs_mtx_context), &(ps_mem->bufs_mtx_context.virtual_addr));
3050    if (ps_mem->bufs_mtx_context.virtual_addr == NULL) {
3051        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s error: mapping sei header\n", __FUNCTION__);
3052        return ;
3053    }
3054    psMtxEncContext = (IMG_MTX_VIDEO_CONTEXT*)(ps_mem->bufs_mtx_context.virtual_addr);
3055
3056    tng_cmdbuf_set_phys(&(psMtxEncContext->ui32MVSettingsBTable), 0,
3057        &(ps_mem->bufs_mv_setting_btable), 0, 0);
3058    if (ctx->sRCParams.b16Hierarchical)
3059        tng_cmdbuf_set_phys(&psMtxEncContext->ui32MVSettingsHierarchical, 0,
3060            &(ps_mem->bufs_mv_setting_hierar), 0, 0);
3061#ifdef _TNG_FRAMES_
3062    tng_cmdbuf_set_phys(psMtxEncContext->apReconstructured, ctx->i32PicNodes,
3063        &(ps_mem->bufs_recon_pictures), 0, ps_mem_size->recon_pictures);
3064#else
3065    for (i = 0; i < ctx->i32PicNodes; i++) {
3066        tng_cmdbuf_set_phys(&(psMtxEncContext->apReconstructured[i]), 0,
3067            &(ps_buf->ref_surface[i]->psb_surface->buf), 0, 0);
3068    }
3069#endif
3070
3071    tng_cmdbuf_set_phys(psMtxEncContext->apColocated, ctx->i32PicNodes,
3072        &(ps_mem->bufs_colocated), 0, ps_mem_size->colocated);
3073
3074    tng_cmdbuf_set_phys(psMtxEncContext->apMV, ctx->i32MVStores,
3075        &(ps_mem->bufs_mv), 0, ps_mem_size->mv);
3076
3077    if (ctx->bEnableMVC) {
3078        tng_cmdbuf_set_phys(psMtxEncContext->apInterViewMV, 2,
3079            &(ps_mem->bufs_interview_mv), 0, ps_mem_size->interview_mv);
3080    }
3081
3082    tng_cmdbuf_set_phys(psMtxEncContext->apWritebackRegions, WB_FIFO_SIZE,
3083        &(ctx->bufs_writeback), 0, ps_mem_size->writeback);
3084
3085    tng_cmdbuf_set_phys(psMtxEncContext->apAboveParams, (IMG_UINT32)(ctx->ui8PipesToUse),
3086        &(ps_mem->bufs_above_params), 0, ps_mem_size->above_params);
3087
3088    // SEI_INSERTION
3089    if (ctx->bInsertHRDParams) {
3090        tng_cmdbuf_set_phys(&psMtxEncContext->pSEIBufferingPeriodTemplate, 0,
3091            &(ps_mem->bufs_sei_header), ps_mem_size->sei_header, ps_mem_size->sei_header);
3092        tng_cmdbuf_set_phys(&psMtxEncContext->pSEIPictureTimingTemplate, 0,
3093            &(ps_mem->bufs_sei_header), ps_mem_size->sei_header * 2, ps_mem_size->sei_header);
3094    }
3095
3096    tng_cmdbuf_set_phys(psMtxEncContext->apSliceParamsTemplates, NUM_SLICE_TYPES,
3097        &(ps_mem->bufs_slice_template), 0, ps_mem_size->slice_template);
3098
3099    tng_cmdbuf_set_phys(psMtxEncContext->aui32SliceMap, ctx->ui8SlotsInUse,
3100        &(ps_mem->bufs_slice_map), 0, ps_mem_size->slice_map);
3101
3102    // WEIGHTED PREDICTION
3103    if (ctx->bWeightedPrediction || (ctx->ui8VPWeightedImplicitBiPred == WBI_EXPLICIT)) {
3104        tng_cmdbuf_set_phys(psMtxEncContext->aui32WeightedPredictionVirtAddr, ctx->ui8SlotsInUse,
3105            &(ps_mem->bufs_weighted_prediction), 0, ps_mem_size->weighted_prediction);
3106    }
3107
3108    tng_cmdbuf_set_phys(&psMtxEncContext->ui32FlatGopStruct, 0, &(ps_mem->bufs_flat_gop), 0, 0);
3109    if (psMtxEncContext->b8Hierarchical)
3110        tng_cmdbuf_set_phys(&psMtxEncContext->ui32HierarGopStruct, 0, &(ps_mem->bufs_hierar_gop), 0, 0);
3111
3112#ifdef LTREFHEADER
3113    tng_cmdbuf_set_phys(psMtxEncContext->aui32LTRefHeader, ctx->ui8SlotsInUse,
3114        &(ps_mem->bufs_lt_ref_header), 0, ps_mem_size->lt_ref_header);
3115#endif
3116
3117    tng_cmdbuf_set_phys(psMtxEncContext->apPicHdrTemplates, 4,
3118        &(ps_mem->bufs_pic_template), 0, ps_mem_size->pic_template);
3119
3120    if (ctx->eStandard == IMG_STANDARD_H264) {
3121        tng_cmdbuf_set_phys(&(psMtxEncContext->apSeqHeader), 0,
3122            &(ps_mem->bufs_seq_header), 0, ps_mem_size->seq_header);
3123        if (ctx->bEnableMVC)
3124            tng_cmdbuf_set_phys(&(psMtxEncContext->apSubSetSeqHeader), 0,
3125                &(ps_mem->bufs_sub_seq_header), 0, ps_mem_size->seq_header);
3126    }
3127
3128    if (ctx->ui8EnableSelStatsFlags & ESF_FIRST_STAGE_STATS) {
3129        tng_cmdbuf_set_phys(psMtxEncContext->pFirstPassOutParamAddr, ctx->ui8SlotsInUse,
3130            &(ps_mem->bufs_first_pass_out_params), 0, ps_mem_size->first_pass_out_params);
3131    }
3132
3133#ifndef EXCLUDE_BEST_MP_DECISION_DATA
3134    // Store the feedback memory address for all "5" slots in the context
3135    if (ctx->ui8EnableSelStatsFlags & ESF_MP_BEST_MB_DECISION_STATS
3136        || ctx->ui8EnableSelStatsFlags & ESF_MP_BEST_MOTION_VECTOR_STATS) {
3137        tng_cmdbuf_set_phys(psMtxEncContext->pFirstPassOutBestMultipassParamAddr, ctx->ui8SlotsInUse,
3138            &(ps_mem->bufs_first_pass_out_best_multipass_param), 0, ps_mem_size->first_pass_out_best_multipass_param);
3139    }
3140#endif
3141
3142    //Store the MB-Input control parameter memory for all the 5-slots in the context
3143    if (ctx->bEnableInpCtrl) {
3144        tng_cmdbuf_set_phys(psMtxEncContext->pMBCtrlInParamsAddr, ctx->ui8SlotsInUse,
3145            &(ps_mem->bufs_mb_ctrl_in_params), 0, ps_mem_size->mb_ctrl_in_params);
3146    }
3147
3148    psb_buffer_unmap(&(ps_mem->bufs_mtx_context));
3149
3150    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s end\n", __FUNCTION__);
3151
3152    return ;
3153}
3154
3155static VAStatus tng__validate_params(context_ENC_p ctx)
3156{
3157    VAStatus vaStatus = VA_STATUS_SUCCESS;
3158    IMG_UINT16 ui16WidthInMbs = (ctx->ui16Width + 15) >> 4;
3159    IMG_UINT16 ui16PictureHeight = ((ctx->ui16FrameHeight >> (ctx->bIsInterlaced ? 1 : 0)) + 15) & ~15;
3160    IMG_UINT16 ui16FrameHeightInMbs = (ctx->ui16FrameHeight + 15) >> 4;
3161
3162    if ((ctx->ui16Width & 0xf) != 0) {
3163        return VA_STATUS_ERROR_INVALID_PARAMETER;
3164    }
3165
3166    if ((ctx->ui16FrameHeight & 0xf) != 0) {
3167        return VA_STATUS_ERROR_INVALID_PARAMETER;
3168    }
3169
3170    ctx->uMBspS = ui16WidthInMbs * ui16FrameHeightInMbs * ctx->sRCParams.ui32FrameRate;
3171
3172    if (ctx->ui32CoreRev >= MIN_36_REV) {
3173        if ((ctx->ui16Width > 4096) || (ctx->ui16PictureHeight > 4096)) {
3174            return VA_STATUS_ERROR_INVALID_PARAMETER;
3175        }
3176        if ((ui16WidthInMbs << 4) * ui16PictureHeight > 2048 * 2048) {
3177            return VA_STATUS_ERROR_INVALID_PARAMETER;
3178        }
3179    } else {
3180        if ((ctx->ui16Width > 2048) || (ui16PictureHeight > 2048)) {
3181            return VA_STATUS_ERROR_INVALID_PARAMETER;
3182        }
3183    }
3184
3185    if (ctx->eStandard == IMG_STANDARD_H264) {
3186        if ((ctx->ui8DeblockIDC == 0) && (ctx->bArbitrarySO))
3187            ctx->ui8DeblockIDC = 2;
3188
3189        if ((ctx->ui8DeblockIDC == 0) && ((IMG_UINT32)(ctx->ui8PipesToUse) > 1) && (ctx->ui8SlicesPerPicture > 1)) {
3190            drv_debug_msg(VIDEO_DEBUG_GENERAL, "WARNING: Full deblocking with multiple pipes will cause a mismatch between reconstructed and encoded video\n");
3191            drv_debug_msg(VIDEO_DEBUG_GENERAL, "Consider using -deblockIDC 2 or -deblockIDC 1 instead if matching reconstructed video is required.\n");
3192            drv_debug_msg(VIDEO_DEBUG_GENERAL, "WARNING: Forcing -deblockIDC = 2 for HW verification.\n");
3193            ctx->ui8DeblockIDC = 2;
3194        }
3195    } else if (ctx->eStandard == IMG_STANDARD_H263) {
3196		ctx->bArbitrarySO = IMG_FALSE;
3197		ctx->ui8DeblockIDC = 1;
3198    } else {
3199        ctx->ui8DeblockIDC = 1;
3200    }
3201
3202    //ctx->sRCParams.ui32SliceByteLimit = 0;
3203    ctx->sRCParams.ui32SliceMBLimit = 0;
3204    //slice params
3205    if (ctx->ui8SlicesPerPicture == 0)
3206        ctx->ui8SlicesPerPicture = ctx->sCapsParams.ui16RecommendedSlices;
3207    else {
3208        if (ctx->ui8SlicesPerPicture > ctx->sCapsParams.ui16MaxSlices)
3209            ctx->ui8SlicesPerPicture = ctx->sCapsParams.ui16MaxSlices;
3210        else if (ctx->ui8SlicesPerPicture < ctx->sCapsParams.ui16MinSlices)
3211            ctx->ui8SlicesPerPicture = ctx->sCapsParams.ui16MinSlices;
3212    }
3213
3214    if (ctx->ui32pseudo_rand_seed == UNINIT_PARAM) {
3215        // When -randseed is uninitialised, initialise seed using other commandline values
3216        ctx->ui32pseudo_rand_seed = (IMG_UINT32) ((ctx->sRCParams.ui32InitialQp +
3217            ctx->ui16PictureHeight + ctx->ui16Width + ctx->sRCParams.ui32BitsPerSecond) & 0xffffffff);
3218        // iQP_Luma + pParams->uHeight + pParams->uWidth + pParams->uBitRate) & 0xffffffff);
3219    }
3220
3221    if (ctx->eStandard == IMG_STANDARD_H264) {
3222        ctx->ui8PipesToUse = tng__min(ctx->ui8PipesToUse, ctx->ui8SlicesPerPicture);
3223    } else {
3224        ctx->ui8PipesToUse = 1;
3225    }
3226
3227    return vaStatus;
3228}
3229
3230static VAStatus tng__validate_busize(context_ENC_p ctx)
3231{
3232    //IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
3233    // if no BU size is given then pick one ourselves, if doing arbitrary slice order then make BU = width in bu's
3234    // forces slice boundaries to no be mid-row
3235    if (ctx->bArbitrarySO || (ctx->ui32BasicUnit == 0)) {
3236        ctx->ui32BasicUnit = (ctx->ui16Width / 16);
3237        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Patched Basic unit to %d\n", ctx->ui32BasicUnit);
3238    } else {
3239        IMG_UINT32 ui32MBs, ui32MBsperSlice, ui32MBsLastSlice;
3240        IMG_UINT32 ui32BUs;
3241        IMG_INT32  i32SliceHeight;
3242        IMG_UINT32 ui32MaxSlicesPerPipe, ui32MaxMBsPerPipe, ui32MaxBUsPerPipe;
3243
3244        ui32MBs  = ctx->ui16PictureHeight * ctx->ui16Width / (16 * 16);
3245
3246        i32SliceHeight = ctx->ui16PictureHeight / ctx->ui8SlicesPerPicture;
3247        i32SliceHeight &= ~15;
3248
3249        ui32MBsperSlice = (i32SliceHeight * ctx->ui16Width) / (16 * 16);
3250        ui32MBsLastSlice = ui32MBs - (ui32MBsperSlice * (ctx->ui8SlicesPerPicture - 1));
3251
3252        // they have given us a basic unit so validate it
3253        if (ctx->ui32BasicUnit < 6) {
3254            drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nERROR: Basic unit size too small, must be greater than 6\n");
3255            return VA_STATUS_ERROR_UNKNOWN;
3256        }
3257
3258        if (ctx->ui32BasicUnit > ui32MBsperSlice) {
3259            drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nERROR: Basic unit size(%d) too large", ctx->ui32BasicUnit);
3260            drv_debug_msg(VIDEO_DEBUG_GENERAL, " must not be greater than the number of macroblocks in a slice (%d)\n", ui32MBsperSlice);
3261            return VA_STATUS_ERROR_UNKNOWN;
3262        }
3263        if (ctx->ui32BasicUnit > ui32MBsLastSlice) {
3264            drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nERROR: Basic unit size(%d) too large", ctx->ui32BasicUnit);
3265            drv_debug_msg(VIDEO_DEBUG_GENERAL, " must not be greater than the number of macroblocks in a slice (%d)\n", ui32MBsLastSlice);
3266            return VA_STATUS_ERROR_UNKNOWN;
3267        }
3268
3269        ui32BUs = ui32MBsperSlice / ctx->ui32BasicUnit;
3270        if ((ui32BUs * ctx->ui32BasicUnit) != ui32MBsperSlice) {
3271            drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nERROR: Basic unit size(%d) not an integer divisor of MB's in a slice(%d)",
3272                                     ctx->ui32BasicUnit, ui32MBsperSlice);
3273            return VA_STATUS_ERROR_UNKNOWN;
3274        }
3275
3276        ui32BUs = ui32MBsLastSlice / ctx->ui32BasicUnit;
3277        if ((ui32BUs * ctx->ui32BasicUnit) != ui32MBsLastSlice) {
3278            drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nERROR: Basic unit size(%d) not an integer divisor of MB's in the last slice(%d)",
3279                                     ctx->ui32BasicUnit, ui32MBsLastSlice);
3280            return VA_STATUS_ERROR_UNKNOWN;
3281        }
3282
3283        // check if the number of BUs per pipe is greater than 200
3284        ui32MaxSlicesPerPipe = (IMG_UINT32)(ctx->ui8SlicesPerPicture + ctx->ui8PipesToUse - 1) / (IMG_UINT32)(ctx->ui8PipesToUse);
3285        ui32MaxMBsPerPipe = (ui32MBsperSlice * (ui32MaxSlicesPerPipe - 1)) + ui32MBsLastSlice;
3286        ui32MaxBUsPerPipe = (ui32MaxMBsPerPipe + ctx->ui32BasicUnit - 1) / ctx->ui32BasicUnit;
3287        if (ui32MaxBUsPerPipe > 200) {
3288            drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nERROR: Basic unit size too small. There must be less than 201 basic units per slice");
3289            return VA_STATUS_ERROR_UNKNOWN;
3290        }
3291    }
3292
3293    ctx->sRCParams.ui32BUSize = ctx->ui32BasicUnit;
3294    return VA_STATUS_SUCCESS;
3295}
3296
3297static VAStatus tng__cmdbuf_new_codec(context_ENC_p ctx)
3298{
3299     VAStatus vaStatus = VA_STATUS_SUCCESS;
3300     tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
3301     psb_driver_data_p driver_data = ctx->obj_context->driver_data;
3302     context_ENC_mem *ps_mem = &(ctx->ctx_mem[0]);
3303
3304     *cmdbuf->cmd_idx++ =
3305        ((MTX_CMDID_SW_NEW_CODEC & MTX_CMDWORD_ID_MASK) << MTX_CMDWORD_ID_SHIFT) |
3306        ((ctx->eCodec        & MTX_CMDWORD_CORE_MASK) << MTX_CMDWORD_CORE_SHIFT) |
3307        (((driver_data->context_id & MTX_CMDWORD_COUNT_MASK) << MTX_CMDWORD_COUNT_SHIFT));
3308 //       (((driver_data->drm_context & MTX_CMDWORD_COUNT_MASK) << MTX_CMDWORD_COUNT_SHIFT));
3309
3310     tng_cmdbuf_insert_command_param((ctx->ui16Width << 16) | ctx->ui16PictureHeight);
3311
3312    return vaStatus;
3313}
3314
3315static VAStatus tng__cmdbuf_doheader(context_ENC_p ctx)
3316{
3317    VAStatus vaStatus = VA_STATUS_SUCCESS;
3318    context_ENC_mem *ps_mem = &(ctx->ctx_mem[ctx->ui32StreamID]);
3319     tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
3320
3321    cmdbuf->cmd_idx_saved[TNG_CMDBUF_PIC_HEADER_IDX] = cmdbuf->cmd_idx;
3322    tng_cmdbuf_insert_command(ctx->obj_context, 0,
3323                                      MTX_CMDID_DO_HEADER,
3324                                      0,
3325                                      &(ps_mem->bufs_seq_header),
3326                                      0);
3327    return vaStatus;
3328}
3329
3330static VAStatus tng__cmdbuf_lowpower(context_ENC_p ctx)
3331{
3332    VAStatus vaStatus = VA_STATUS_SUCCESS;
3333    tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
3334    psb_driver_data_p driver_data = ctx->obj_context->driver_data;
3335
3336    *cmdbuf->cmd_idx++ =
3337        ((MTX_CMDID_SW_LEAVE_LOWPOWER & MTX_CMDWORD_ID_MASK) << MTX_CMDWORD_ID_SHIFT) |
3338        (((ctx->ui32RawFrameCount == 0 ? 1 : 0)  & MTX_CMDWORD_CORE_MASK) << MTX_CMDWORD_CORE_SHIFT) |
3339        (((driver_data->context_id & MTX_CMDWORD_COUNT_MASK) << MTX_CMDWORD_COUNT_SHIFT));
3340
3341    tng_cmdbuf_insert_command_param(ctx->eCodec);
3342
3343    return vaStatus;
3344}
3345
3346static VAStatus tng__cmdbuf_load_bias(context_ENC_p ctx)
3347{
3348    VAStatus vaStatus = VA_STATUS_SUCCESS;
3349
3350    //init bias parameters
3351     tng_init_bias_params(ctx);
3352
3353     vaStatus = tng__generate_bias(ctx);
3354     if (vaStatus != VA_STATUS_SUCCESS) {
3355         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: generate bias params\n", __FUNCTION__, vaStatus);
3356     }
3357
3358     vaStatus = tng_load_bias(ctx, IMG_INTER_P);
3359     if (vaStatus != VA_STATUS_SUCCESS) {
3360         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: load bias params\n", __FUNCTION__, vaStatus);
3361     }
3362    return vaStatus;
3363}
3364
3365static VAStatus tng__cmdbuf_setvideo(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
3366{
3367    VAStatus vaStatus = VA_STATUS_SUCCESS;
3368    context_ENC_mem *ps_mem = &(ctx->ctx_mem[ui32StreamIndex]);
3369
3370    tng__setvideo_params(ctx, ui32StreamIndex);
3371    tng__setvideo_cmdbuf(ctx, ui32StreamIndex);
3372
3373    tng_cmdbuf_insert_command(ctx->obj_context, ctx->ui32StreamID,
3374        MTX_CMDID_SETVIDEO, 0, &(ps_mem->bufs_mtx_context), 0);
3375
3376    return vaStatus;
3377}
3378
3379static void tng__rc_update(
3380    context_ENC_p ctx,
3381    IMG_UINT32 ui32NewBitrate,
3382    IMG_UINT8 ui8NewFrameQP,
3383    IMG_UINT8 ui8NewFrameMinQP,
3384    IMG_UINT8 ui8NewFrameMaxQP,
3385    IMG_UINT16 ui16NewIntraPeriod)
3386{
3387    tng_cmdbuf_insert_command(ctx->obj_context,
3388	ctx->ui32StreamID,
3389	MTX_CMDID_RC_UPDATE,
3390	F_ENCODE(ui8NewFrameQP, MTX_MSG_RC_UPDATE_QP) |
3391	F_ENCODE(ui32NewBitrate, MTX_MSG_RC_UPDATE_BITRATE),
3392	F_ENCODE(ui8NewFrameMinQP, MTX_MSG_RC_UPDATE_MIN_QP) |
3393	F_ENCODE(ui8NewFrameMaxQP, MTX_MSG_RC_UPDATE_MAX_QP) |
3394	F_ENCODE(ui16NewIntraPeriod, MTX_MSG_RC_UPDATE_INTRA),
3395	0);
3396}
3397
3398static VAStatus tng__update_ratecontrol(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
3399{
3400    VAStatus vaStatus = VA_STATUS_SUCCESS;
3401    IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
3402    IMG_UINT32 ui32CmdData = 0;
3403    IMG_UINT32 ui32NewBitsPerFrame = 0;
3404    IMG_UINT8 ui8NewVCMIFrameQP = 0;
3405
3406    if (!(ctx->rc_update_flag))
3407        return vaStatus;
3408
3409    tng__setup_rcdata(ctx);
3410
3411    drv_debug_msg(VIDEO_DEBUG_GENERAL,
3412        "%s: frame[%d] bits_per_second = %d, min_qp = %d, max_qp = %d, initial_qp = %d\n",
3413        __FUNCTION__, ctx->ui32FrameCount[ui32StreamIndex], psRCParams->ui32BitsPerSecond,
3414        psRCParams->iMinQP, ctx->max_qp, psRCParams->ui32InitialQp);
3415
3416    if (ctx->rc_update_flag & RC_MASK_frame_rate) {
3417	tng__rc_update(ctx, psRCParams->ui32BitsPerSecond, -1, -1, -1, -1);
3418	ctx->rc_update_flag &= ~RC_MASK_frame_rate;
3419    }
3420
3421    if (ctx->rc_update_flag & RC_MASK_bits_per_second) {
3422	tng__rc_update(ctx, psRCParams->ui32BitsPerSecond, -1, -1, -1, -1);
3423	ctx->rc_update_flag &= ~RC_MASK_bits_per_second;
3424    }
3425
3426    if (ctx->rc_update_flag & RC_MASK_min_qp) {
3427	tng__rc_update(ctx, -1, -1, psRCParams->iMinQP, -1, -1);
3428	ctx->rc_update_flag &= ~RC_MASK_min_qp;
3429    }
3430
3431    if (ctx->rc_update_flag & RC_MASK_max_qp) {
3432	tng__rc_update(ctx, -1, -1, -1, ctx->max_qp, -1);
3433	ctx->rc_update_flag &= ~RC_MASK_max_qp;
3434    }
3435
3436    if (ctx->rc_update_flag & RC_MASK_initial_qp) {
3437	tng__rc_update(ctx, -1, psRCParams->ui32InitialQp, -1, -1, -1);
3438	ctx->rc_update_flag &= ~RC_MASK_initial_qp;
3439    }
3440
3441    if (ctx->rc_update_flag & RC_MASK_intra_period) {
3442	tng__rc_update(ctx, -1, -1, -1, -1, ctx->ui32IntraCnt);
3443	ctx->rc_update_flag &= ~RC_MASK_intra_period;
3444    }
3445
3446    return vaStatus;
3447}
3448
3449static VAStatus tng__update_frametype(context_ENC_p ctx, IMG_FRAME_TYPE eFrameType)
3450{
3451    VAStatus vaStatus = VA_STATUS_SUCCESS;
3452    IMG_UINT32 ui32CmdData = 0;
3453
3454    ui32CmdData = F_ENCODE(IMG_PICMGMT_REF_TYPE, MTX_MSG_PICMGMT_SUBTYPE) |
3455                F_ENCODE(eFrameType, MTX_MSG_PICMGMT_DATA);
3456
3457    tng_cmdbuf_insert_command(ctx->obj_context, ctx->ui32StreamID,
3458        MTX_CMDID_PICMGMT ,
3459        ui32CmdData, 0, 0);
3460
3461    return vaStatus;
3462}
3463
3464static VAStatus tng__cmdbuf_send_picmgmt(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
3465{
3466    VAStatus vaStatus = VA_STATUS_SUCCESS;
3467    IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
3468
3469    if (!(ctx->rc_update_flag))
3470        return vaStatus;
3471
3472    //tng__setup_rcdata(ctx);
3473    drv_debug_msg(VIDEO_DEBUG_GENERAL,
3474        "%s: ui32BitsPerSecond = %d, ui32FrameRate = %d, ui32InitialQp = %d\n",
3475        __FUNCTION__, psRCParams->ui32BitsPerSecond,
3476        psRCParams->ui32FrameRate, psRCParams->ui32InitialQp);
3477    drv_debug_msg(VIDEO_DEBUG_GENERAL,
3478        "%s: frame_count[%d] = %d\n", __FUNCTION__,
3479        ui32StreamIndex, ctx->ui32FrameCount[ui32StreamIndex]);
3480
3481    return vaStatus;
3482}
3483
3484
3485static VAStatus tng__cmdbuf_provide_buffer(context_ENC_p ctx, IMG_UINT32 ui32StreamIndex)
3486{
3487    VAStatus vaStatus = VA_STATUS_SUCCESS;
3488
3489    if (ctx->ui8PipesToUse == 1) {
3490        tng_send_codedbuf(ctx, ctx->ui8SlotsCoded);
3491    } else {
3492        /*Make sure DMA start is 128bits alignment*/
3493        tng_send_codedbuf(ctx, ctx->ui8SlotsCoded * 2);
3494        tng_send_codedbuf(ctx, ctx->ui8SlotsCoded * 2 + 1);
3495    }
3496
3497    if (ctx->sRCParams.ui16BFrames > 0)
3498        tng__provide_buffer_BFrames(ctx, ui32StreamIndex);
3499    else
3500        tng__provide_buffer_PFrames(ctx, ui32StreamIndex);
3501/*
3502    if (ctx->ui32LastPicture != 0) {
3503        drv_debug_msg(VIDEO_DEBUG_GENERAL,
3504            "%s: frame_count[%d] = %d\n", __FUNCTION__,
3505            ui32StreamIndex, ctx->ui32FrameCount[ui32StreamIndex]);
3506        tng_picmgmt_update(ctx,IMG_PICMGMT_EOS, ctx->ui32LastPicture);
3507    }
3508*/
3509#ifdef _TOPAZHP_REC_
3510    tng_send_rec_frames(ctx, -1, 0);
3511    tng_send_ref_frames(ctx, 0, 0);
3512    tng_send_ref_frames(ctx, 1, 0);
3513#endif
3514
3515    ctx->ui8SlotsCoded = (ctx->ui8SlotsCoded + 1) & 1;
3516
3517    return vaStatus;
3518}
3519
3520VAStatus tng__set_ctx_buf(context_ENC_p ctx, IMG_UINT32 ui32StreamID)
3521{
3522    VAStatus vaStatus = VA_STATUS_SUCCESS;
3523    IMG_UINT8 ui8IsJpeg;
3524    vaStatus = tng__validate_params(ctx);
3525    if (vaStatus != VA_STATUS_SUCCESS) {
3526        drv_debug_msg(VIDEO_DEBUG_ERROR, "validate params");
3527    }
3528
3529    vaStatus = tng__validate_busize(ctx);
3530    if (vaStatus != VA_STATUS_SUCCESS) {
3531        drv_debug_msg(VIDEO_DEBUG_ERROR, "validate busize");
3532    }
3533    ctx->ctx_cmdbuf[0].ui32LowCmdCount = 0xa5a5a5a5 %  MAX_TOPAZ_CMD_COUNT;
3534    ctx->ctx_cmdbuf[0].ui32HighCmdCount = 0;
3535    ctx->ctx_cmdbuf[0].ui32HighWBReceived = 0;
3536
3537    ui8IsJpeg = (ctx->eStandard == IMG_STANDARD_JPEG) ? 1 : 0;
3538    vaStatus = tng__alloc_context_buffer(ctx, ui8IsJpeg, 0);
3539    if (vaStatus != VA_STATUS_SUCCESS) {
3540        drv_debug_msg(VIDEO_DEBUG_ERROR, "setup enc profile");
3541    }
3542    return vaStatus;
3543}
3544
3545static VAStatus tng__set_headers (context_ENC_p ctx, IMG_UINT32 ui32StreamID)
3546{
3547    VAStatus vaStatus = VA_STATUS_SUCCESS;
3548    IMG_UINT8 ui8SlotIdx = 0;
3549
3550    vaStatus = tng__prepare_templates(ctx, 0);
3551    if (vaStatus != VA_STATUS_SUCCESS) {
3552        drv_debug_msg(VIDEO_DEBUG_ERROR, "prepare_templates\n");
3553    }
3554
3555    for (ui8SlotIdx = 0; ui8SlotIdx < ctx->ui8SlotsInUse; ui8SlotIdx++)
3556        tng_fill_slice_map(ctx, (IMG_UINT32)ui8SlotIdx, 0);
3557
3558    return vaStatus;
3559}
3560
3561static VAStatus tng__set_cmd_buf(context_ENC_p ctx, IMG_UINT32 ui32StreamID)
3562{
3563    VAStatus vaStatus = VA_STATUS_SUCCESS;
3564    vaStatus = tng__cmdbuf_new_codec(ctx);
3565    if (vaStatus != VA_STATUS_SUCCESS) {
3566        drv_debug_msg(VIDEO_DEBUG_ERROR, "cmdbuf new codec\n");
3567    }
3568
3569    vaStatus = tng__cmdbuf_lowpower(ctx);
3570    if (vaStatus != VA_STATUS_SUCCESS) {
3571        drv_debug_msg(VIDEO_DEBUG_ERROR, "cmdbuf lowpower\n");
3572    }
3573
3574    vaStatus = tng__cmdbuf_load_bias(ctx);
3575    if (vaStatus != VA_STATUS_SUCCESS) {
3576        drv_debug_msg(VIDEO_DEBUG_ERROR, "cmdbuf load bias\n");
3577    }
3578
3579    vaStatus = tng__cmdbuf_setvideo(ctx, 0);
3580    if (vaStatus != VA_STATUS_SUCCESS) {
3581        drv_debug_msg(VIDEO_DEBUG_ERROR, "cmdbuf setvideo\n");
3582    }
3583    return vaStatus;
3584}
3585
3586VAStatus tng__end_one_frame(context_ENC_p ctx, IMG_UINT32 ui32StreamID)
3587{
3588    VAStatus vaStatus = VA_STATUS_SUCCESS;
3589    context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
3590
3591    /* save current settings */
3592    ps_buf->previous_src_surface = ps_buf->src_surface;
3593#ifdef _TNG_FRAMES_
3594    ps_buf->previous_ref_surface = ps_buf->ref_surface;
3595#else
3596    ps_buf->previous_ref_surface = ps_buf->ref_surface[0];
3597#endif
3598
3599    /*Frame Skip flag in Coded Buffer of frame N determines if frame N+2
3600    * should be skipped, which means sending encoding commands of frame N+1 doesn't
3601    * have to wait until frame N is completed encoded. It reduces the precision of
3602    * rate control but improves HD encoding performance a lot.*/
3603    ps_buf->pprevious_coded_buf = ps_buf->previous_coded_buf;
3604    ps_buf->previous_coded_buf = ps_buf->coded_buf;
3605
3606    ctx->ePreFrameType = ctx->eFrameType;
3607
3608    return vaStatus;
3609}
3610
3611VAStatus tng_EndPicture(context_ENC_p ctx)
3612{
3613    VAStatus vaStatus = VA_STATUS_SUCCESS;
3614    tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
3615    context_ENC_mem *ps_mem = &(ctx->ctx_mem[0]);
3616    unsigned int offset;
3617    int value;
3618
3619    drv_debug_msg(VIDEO_DEBUG_GENERAL,"%s: ctx->ui8SlicesPerPicture = %d, ctx->ui32FrameCount[0] = %d\n",
3620         __FUNCTION__, ctx->ui8SlicesPerPicture, ctx->ui32FrameCount[0]);
3621
3622    if (ctx->ui32FrameCount[0] == 0) {
3623        vaStatus = tng__set_ctx_buf(ctx, 0);
3624        if (vaStatus != VA_STATUS_SUCCESS) {
3625            drv_debug_msg(VIDEO_DEBUG_ERROR, "set ctx buf \n");
3626        }
3627        vaStatus = tng__set_headers(ctx, 0);
3628        if (vaStatus != VA_STATUS_SUCCESS) {
3629            drv_debug_msg(VIDEO_DEBUG_ERROR, "set headers \n");
3630        }
3631
3632        vaStatus = tng__set_cmd_buf(ctx, 0);
3633        if (vaStatus != VA_STATUS_SUCCESS) {
3634           drv_debug_msg(VIDEO_DEBUG_ERROR, "set cmd buf \n");
3635        }
3636
3637#ifdef _TOPAZHP_PDUMP_
3638	tng_trace_setvideo(ctx, 0);
3639#endif
3640    } else {
3641        vaStatus = tng__cmdbuf_lowpower(ctx);
3642        if (vaStatus != VA_STATUS_SUCCESS) {
3643            drv_debug_msg(VIDEO_DEBUG_ERROR, "cmdbuf lowpower\n");
3644        }
3645    }
3646
3647    if (ctx->sRCParams.eRCMode != IMG_RCMODE_NONE ||
3648	ctx->rc_update_flag) {
3649        vaStatus = tng__update_ratecontrol(ctx, ctx->ui32StreamID);
3650        if (vaStatus != VA_STATUS_SUCCESS) {
3651            drv_debug_msg(VIDEO_DEBUG_ERROR, "send picmgmt");
3652        }
3653    }
3654
3655    if ((ctx->idr_force_flag == 1) && (ctx->sRCParams.ui16BFrames == 0)){
3656        vaStatus = tng__update_frametype(ctx, IMG_FRAME_IDR);
3657        if (vaStatus != VA_STATUS_SUCCESS) {
3658            drv_debug_msg(VIDEO_DEBUG_ERROR, "send picmgmt IDR");
3659        }
3660        ctx->idr_force_flag =0;
3661    }
3662
3663    vaStatus = tng__cmdbuf_provide_buffer(ctx, ctx->ui32StreamID);
3664    if (vaStatus != VA_STATUS_SUCCESS) {
3665        drv_debug_msg(VIDEO_DEBUG_ERROR, "provide buffer");
3666    }
3667
3668    if (ctx->bEnableAIR == IMG_TRUE ||
3669	ctx->bEnableCIR == IMG_TRUE) {
3670	tng_air_set_input_control(ctx, 0);
3671
3672	if (ctx->bEnableAIR == IMG_TRUE)
3673	    tng_air_set_output_control(ctx, 0);
3674    }
3675
3676    if (ctx->eStandard == IMG_STANDARD_MPEG4) {
3677        if (ctx->ui32FrameCount[0] == 0) {
3678            vaStatus = tng__cmdbuf_doheader(ctx);
3679            if (vaStatus != VA_STATUS_SUCCESS) {
3680                drv_debug_msg(VIDEO_DEBUG_ERROR, "cmdbuf doheader\n");
3681            }
3682        }
3683        tng__MPEG4ES_send_seq_header(ctx, ctx->ui32StreamID);
3684    }
3685
3686    if (ctx->bInsertHRDParams)
3687	tng_cmdbuf_insert_command(ctx->obj_context, ctx->ui32StreamID,
3688	    MTX_CMDID_DO_HEADER, 0, &(ps_mem->bufs_sei_header), 0);
3689
3690    tng_cmdbuf_insert_command(ctx->obj_context, ctx->ui32StreamID,
3691        MTX_CMDID_ENCODE_FRAME, 0, 0, 0);
3692
3693#ifdef _TOPAZHP_CMDBUF_
3694    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s addr = 0x%08x \n", __FUNCTION__, cmdbuf);
3695    tng__trace_cmdbuf_words(cmdbuf);
3696    tng__trace_cmdbuf(cmdbuf, ctx->ui32StreamID);
3697#endif
3698
3699    //    tng_buffer_unmap(ctx, ctx->ui32StreamID);
3700    tng_cmdbuf_mem_unmap(cmdbuf);
3701
3702    vaStatus = tng__end_one_frame(ctx, 0);
3703    if (vaStatus != VA_STATUS_SUCCESS) {
3704       drv_debug_msg(VIDEO_DEBUG_ERROR, "setting when one frame ends\n");
3705    }
3706
3707    if (tng_context_flush_cmdbuf(ctx->obj_context)) {
3708        vaStatus = VA_STATUS_ERROR_UNKNOWN;
3709    }
3710
3711
3712    ++(ctx->ui32FrameCount[ctx->ui32StreamID]);
3713    ++(ctx->ui32RawFrameCount);
3714    return vaStatus;
3715}
3716