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