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