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