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