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