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 <errno.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <stdint.h>
36 #include <string.h>
37 #include <limits.h>
38 
39 #include "hwdefs/coreflags.h"
40 #include "hwdefs/topaz_vlc_regs.h"
41 #include "hwdefs/topaz_db_regs.h"
42 
43 #include "va/va_enc_h264.h"
44 
45 #include "psb_def.h"
46 #include "psb_drv_debug.h"
47 #include "psb_surface.h"
48 #include "tng_cmdbuf.h"
49 #include "tng_hostcode.h"
50 #include "tng_hostheader.h"
51 #include "tng_picmgmt.h"
52 #include "tng_slotorder.h"
53 #include "tng_hostair.h"
54 #include "tng_H264ES.h"
55 #ifdef _TOPAZHP_PDUMP_
56 #include "tng_trace.h"
57 #endif
58 
59 #define TOPAZ_H264_MAX_BITRATE 135000000
60 
61 #define INIT_CONTEXT_H264ES     context_ENC_p ctx = (context_ENC_p) obj_context->format_data
62 #define SURFACE(id)    ((object_surface_p) object_heap_lookup( &ctx->obj_context->driver_data->surface_heap, id ))
63 #define BUFFER(id)  ((object_buffer_p) object_heap_lookup( &ctx->obj_context->driver_data->buffer_heap, id ))
64 
tng__H264ES_init_profile(object_context_p obj_context,object_config_p obj_config)65 static VAStatus tng__H264ES_init_profile(
66     object_context_p obj_context,
67     object_config_p obj_config)
68 {
69     VAStatus vaStatus = VA_STATUS_SUCCESS;
70     context_ENC_p ctx;
71     ctx = (context_ENC_p) obj_context->format_data;
72     switch (obj_config->profile) {
73         case VAProfileH264Baseline:
74         case VAProfileH264ConstrainedBaseline:
75             ctx->ui8ProfileIdc = H264ES_PROFILE_BASELINE;
76             break;
77         case VAProfileH264Main:
78             ctx->ui8ProfileIdc = H264ES_PROFILE_MAIN;
79             break;
80         case VAProfileH264High:
81             ctx->ui8ProfileIdc = H264ES_PROFILE_HIGH;
82             break;
83         case VAProfileH264StereoHigh:
84             ctx->ui8ProfileIdc = H264ES_PROFILE_HIGH;
85             ctx->bEnableMVC = 1;
86             ctx->ui16MVCViewIdx = 0;
87             break;
88         default:
89             ctx->ui8ProfileIdc = H264ES_PROFILE_BASELINE;
90             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
91             break;
92     }
93     drv_debug_msg(VIDEO_DEBUG_GENERAL,
94         "%s: obj_config->profile = %dctx->eStandard = %d, ctx->bEnableMVC = %d\n",
95         __FUNCTION__, obj_config->profile, ctx->eStandard, ctx->bEnableMVC);
96     return vaStatus;
97 }
98 
tng__H264ES_get_codec_type(object_context_p obj_context,object_config_p __maybe_unused obj_config)99 static VAStatus tng__H264ES_get_codec_type(
100     object_context_p obj_context,
101     object_config_p __maybe_unused obj_config)
102 {
103     VAStatus vaStatus = VA_STATUS_SUCCESS;
104     context_ENC_p ctx = (context_ENC_p) obj_context->format_data;
105     IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
106 
107     ctx->eCodec = IMG_CODEC_NUM;
108 
109     if (ctx->bEnableMVC) {
110         switch (psRCParams->eRCMode) {
111             case IMG_RCMODE_NONE:
112                 ctx->eCodec = IMG_CODEC_H264MVC_NO_RC;
113                 break;
114             case IMG_RCMODE_CBR:
115                 ctx->eCodec = IMG_CODEC_H264MVC_CBR;
116                 break;
117             case IMG_RCMODE_VBR:
118                 ctx->eCodec = IMG_CODEC_H264MVC_VBR;
119                 break;
120             default:
121                 drv_debug_msg(VIDEO_DEBUG_ERROR, "RC mode MVC\n");
122                 break;
123         }
124     } else {
125         switch (psRCParams->eRCMode) {
126             case IMG_RCMODE_NONE:
127                 ctx->eCodec = IMG_CODEC_H264_NO_RC;
128                 break;
129             case IMG_RCMODE_CBR:
130                 ctx->eCodec = IMG_CODEC_H264_CBR;
131                 break;
132             case IMG_RCMODE_VBR:
133                 ctx->eCodec = IMG_CODEC_H264_VBR;
134                 break;
135             case IMG_RCMODE_VCM:
136                 ctx->eCodec = IMG_CODEC_H264_VCM;
137                 break;
138             default:
139                 drv_debug_msg(VIDEO_DEBUG_ERROR, "RC mode\n");
140                 break;
141         }
142     }
143     return vaStatus;
144 }
145 
tng__H264ES_init_format_mode(object_context_p obj_context,object_config_p __maybe_unused obj_config)146 static VAStatus tng__H264ES_init_format_mode(
147     object_context_p obj_context,
148     object_config_p __maybe_unused obj_config)
149 {
150     VAStatus vaStatus = VA_STATUS_SUCCESS;
151     context_ENC_p ctx = (context_ENC_p) obj_context->format_data;
152 
153     ctx->bIsInterlaced = IMG_FALSE;
154     ctx->bIsInterleaved = IMG_FALSE;
155     ctx->ui16PictureHeight = ctx->ui16FrameHeight;
156     ctx->eCodec = IMG_CODEC_H264_NO_RC;
157     return vaStatus;
158 }
159 
tng__H264ES_init_context(object_context_p obj_context,object_config_p __maybe_unused obj_config)160 static void tng__H264ES_init_context(object_context_p obj_context,
161     object_config_p __maybe_unused obj_config)
162 {
163     context_ENC_p ctx = (context_ENC_p) obj_context->format_data;
164     //This parameter need not be exposed
165     ctx->ui8InterIntraIndex = 3;
166     ctx->ui8CodedSkippedIndex = 3;
167     ctx->bEnableHostQP = IMG_FALSE;
168     ctx->uMaxChunks = 0xA0;
169     ctx->uChunksPerMb = 0x40;
170     ctx->uPriorityChunks = (0xA0 - 0x60);
171     ctx->ui32FCode = 4;
172     ctx->iFineYSearchSize = 2;
173 
174     //This parameter need not be exposed
175     //host to control the encoding process
176     ctx->bEnableInpCtrl = IMG_FALSE;
177     ctx->bEnableHostBias = IMG_FALSE;
178     //By default false Newly Added
179     ctx->bEnableCumulativeBiases = IMG_FALSE;
180 
181     //Weighted Prediction is not supported in TopazHP Version 3.0
182     ctx->bWeightedPrediction = IMG_FALSE;
183     ctx->ui8VPWeightedImplicitBiPred = 0;
184     ctx->bInsertHRDParams = IMG_FALSE;
185     ctx->bArbitrarySO = IMG_FALSE;
186     ctx->ui32BasicUnit = 0;
187     ctx->idr_force_flag = 0;
188     ctx->bVPAdaptiveRoundingDisable = IMG_FALSE;
189 }
190 
tng__H264ES_process_misc_framerate_param(context_ENC_p ctx,object_buffer_p obj_buffer)191 static VAStatus tng__H264ES_process_misc_framerate_param(context_ENC_p ctx, object_buffer_p obj_buffer)
192 {
193     VAEncMiscParameterBuffer *pBuffer = (VAEncMiscParameterBuffer *) obj_buffer->buffer_data;
194     VAEncMiscParameterFrameRate *psMiscFrameRateParam;
195     IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
196 
197     ASSERT(obj_buffer->type == VAEncMiscParameterTypeFrameRate);
198     ASSERT(obj_buffer->size == sizeof(VAEncMiscParameterFrameRate));
199 
200     psMiscFrameRateParam = (VAEncMiscParameterFrameRate *)(pBuffer->data);
201 
202     if (psMiscFrameRateParam == NULL)
203         return VA_STATUS_ERROR_INVALID_BUFFER;
204 
205     if (psMiscFrameRateParam->framerate < 1 || psMiscFrameRateParam->framerate > 65535)
206         return VA_STATUS_ERROR_INVALID_PARAMETER;
207 
208 
209     if (psRCParams->ui32FrameRate == 0)
210         psRCParams->ui32FrameRate = psMiscFrameRateParam->framerate;
211     else {
212         if(psMiscFrameRateParam->framerate != psRCParams->ui32FrameRate){
213 	    if (psMiscFrameRateParam->framerate > psRCParams->ui32FrameRate)
214 		psRCParams->ui32BitsPerSecond /= (float)psMiscFrameRateParam->framerate / psRCParams->ui32FrameRate;
215 	    else
216 		psRCParams->ui32BitsPerSecond *= (float)psRCParams->ui32FrameRate / psMiscFrameRateParam->framerate;
217             psRCParams->ui32FrameRate = psMiscFrameRateParam->framerate;
218             ctx->rc_update_flag |= RC_MASK_frame_rate;
219         }
220     }
221 
222     return VA_STATUS_SUCCESS;
223 }
224 
tng__H264ES_process_misc_ratecontrol_param(context_ENC_p ctx,object_buffer_p obj_buffer)225 static VAStatus tng__H264ES_process_misc_ratecontrol_param(context_ENC_p ctx, object_buffer_p obj_buffer)
226 {
227     IMG_INT32 ui32BitsPerFrame;
228     VAEncMiscParameterRateControl *psMiscRcParams;
229     IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
230     VAEncMiscParameterBuffer *pBuffer = (VAEncMiscParameterBuffer *) obj_buffer->buffer_data;
231     unsigned int max_bps;
232 
233     ASSERT(obj_buffer->type == VAEncMiscParameterTypeRateControl);
234     ASSERT(obj_buffer->size == sizeof(VAEncMiscParameterRateControl));
235     psMiscRcParams = (VAEncMiscParameterRateControl *)pBuffer->data;
236 
237 #ifdef _TOPAZHP_PDUMP_
238     tng_H264ES_trace_misc_rc_params(psMiscRcParams);
239 #endif
240 
241     drv_debug_msg(VIDEO_DEBUG_GENERAL,
242         "%s psRCParams->ui32BitsPerSecond = %d, psMiscRcParams->bits_per_second = %d \n",
243         __FUNCTION__, psRCParams->ui32BitsPerSecond, psMiscRcParams->bits_per_second);
244 
245     if (psMiscRcParams->bits_per_second > TOPAZ_H264_MAX_BITRATE) {
246         drv_debug_msg(VIDEO_DEBUG_GENERAL,
247             "%s: bits_per_second(%d) exceeds the maximum bitrate, set it with %d\n",
248             __FUNCTION__, psMiscRcParams->bits_per_second, TOPAZ_H264_MAX_BITRATE);
249         psMiscRcParams->bits_per_second = TOPAZ_H264_MAX_BITRATE;
250     }
251 
252     if ((psRCParams->ui32BitsPerSecond != psMiscRcParams->bits_per_second) &&
253         psMiscRcParams->bits_per_second != 0) {
254         psRCParams->ui32BitsPerSecond = psMiscRcParams->bits_per_second;
255 	ctx->rc_update_flag |= RC_MASK_bits_per_second;
256     }
257 
258     drv_debug_msg(VIDEO_DEBUG_GENERAL,
259         "%s: rate control changed from %d to %d\n", __FUNCTION__,
260         psRCParams->ui32BitsPerSecond, psMiscRcParams->bits_per_second);
261 
262     if (psMiscRcParams->rc_flags.value != 0) {
263        if (psMiscRcParams->rc_flags.bits.disable_bit_stuffing)
264            ctx->sRCParams.bDisableBitStuffing = IMG_TRUE;
265        drv_debug_msg(VIDEO_DEBUG_GENERAL, "bDisableBitStuffing is %d\n",
266            ctx->sRCParams.bDisableBitStuffing);
267     }
268 
269     if (psMiscRcParams->window_size > 2000) {
270 	drv_debug_msg(VIDEO_DEBUG_ERROR, "window_size is too much!\n");
271 	return VA_STATUS_ERROR_INVALID_PARAMETER;
272     }
273 
274     if (psMiscRcParams->window_size != 0)
275         ctx->uiCbrBufferTenths = psMiscRcParams->window_size / 100;
276 
277     if (psRCParams->ui32FrameRate == 0)
278         psRCParams->ui32FrameRate = 30;
279 
280     /* According to Table A-1 Level limits, if resolution is bigger than 625SD,
281        min compression ratio is 4, otherwise min compression ratio is 2 */
282     if (psRCParams->ui32BitsPerSecond == 0) {
283 	max_bps =  (ctx->obj_context->picture_width * ctx->obj_context->picture_height * 3 / 2 ) * 8 * psRCParams->ui32FrameRate;
284 	if (ctx->ui16SourceWidth > 720)
285 	    max_bps /= 4;
286 	else
287 	    max_bps /= 2;
288 	psRCParams->ui32BitsPerSecond = max_bps;
289     }
290 
291     if (ctx->uiCbrBufferTenths) {
292         psRCParams->ui32BufferSize = (IMG_UINT32)(psRCParams->ui32BitsPerSecond * ctx->uiCbrBufferTenths / 10.0);
293     } else {
294         if (psRCParams->ui32BitsPerSecond < 256000)
295             psRCParams->ui32BufferSize = ((9 * psRCParams->ui32BitsPerSecond) >> 1);
296         else
297             psRCParams->ui32BufferSize = ((5 * psRCParams->ui32BitsPerSecond) >> 1);
298     }
299 
300     drv_debug_msg(VIDEO_DEBUG_GENERAL,
301         "%s ctx->uiCbrBufferTenths = %d, psRCParams->ui32BufferSize = %d\n",
302         __FUNCTION__, ctx->uiCbrBufferTenths, psRCParams->ui32BufferSize);
303     drv_debug_msg(VIDEO_DEBUG_GENERAL,
304         "%s psRCParams->ui32BitsPerSecond = %d, psMiscRcParams->bits_per_second = %d\n",
305         __FUNCTION__, psRCParams->ui32BitsPerSecond, psMiscRcParams->bits_per_second);
306 
307     //psRCParams->ui32BUSize = psMiscRcParams->basic_unit_size;
308     psRCParams->i32InitialDelay = (13 * psRCParams->ui32BufferSize) >> 4;
309     psRCParams->i32InitialLevel = (3 * psRCParams->ui32BufferSize) >> 4;
310 
311     ui32BitsPerFrame = psRCParams->ui32BitsPerSecond / psRCParams->ui32FrameRate;
312     /* in order to minimise mismatches between firmware and external world InitialLevel should be a multiple of ui32BitsPerFrame */
313     psRCParams->i32InitialLevel = ((psRCParams->i32InitialLevel + ui32BitsPerFrame / 2) / ui32BitsPerFrame) * ui32BitsPerFrame;
314     psRCParams->i32InitialLevel = tng__max(psRCParams->i32InitialLevel, ui32BitsPerFrame);
315     psRCParams->i32InitialDelay = psRCParams->ui32BufferSize - psRCParams->i32InitialLevel;
316 
317     //free(psMiscRcParams);
318     if (psMiscRcParams->initial_qp > 51 ||
319 	psMiscRcParams->min_qp > 51 ||
320 	psMiscRcParams->max_qp > 51) {
321         drv_debug_msg(VIDEO_DEBUG_ERROR,
322             "%s: Initial_qp(%d) min_qp(%d) max_qp(%d) invalid.\nQP shouldn't be larger than 51 for H264\n",
323             __FUNCTION__, psMiscRcParams->initial_qp, psMiscRcParams->min_qp, psMiscRcParams->max_qp);
324         return VA_STATUS_ERROR_INVALID_PARAMETER;
325     }
326 
327     if ((psRCParams->ui32InitialQp != psMiscRcParams->initial_qp) &&
328 	(psMiscRcParams->initial_qp != 0)) {
329 	drv_debug_msg(VIDEO_DEBUG_GENERAL,
330 	    "%s: initial_qp updated from %d to %d\n",
331 	    __FUNCTION__, psRCParams->ui32InitialQp, psMiscRcParams->initial_qp);
332 	ctx->rc_update_flag |= RC_MASK_initial_qp;
333 	psRCParams->ui32InitialQp = psMiscRcParams->initial_qp;
334     }
335 
336     if ((psRCParams->iMinQP != psMiscRcParams->min_qp) &&
337 	(psMiscRcParams->min_qp != 0)) {
338 	drv_debug_msg(VIDEO_DEBUG_GENERAL,
339 	    "%s: min_qp updated from %d to %d\n",
340 	    __FUNCTION__, psRCParams->iMinQP, psMiscRcParams->min_qp);
341 	ctx->rc_update_flag |= RC_MASK_min_qp;
342 	psRCParams->iMinQP = psMiscRcParams->min_qp;
343     }
344 
345     if ((ctx->max_qp != psMiscRcParams->max_qp) &&
346 	(psMiscRcParams->max_qp != 0)) {
347 	drv_debug_msg(VIDEO_DEBUG_GENERAL,
348 	    "%s: max_qp updated from %d to %d\n",
349 	    __FUNCTION__, ctx->max_qp, psMiscRcParams->max_qp);
350 	ctx->rc_update_flag |= RC_MASK_max_qp;
351 	ctx->max_qp = psMiscRcParams->max_qp;
352     }
353 
354     return VA_STATUS_SUCCESS;
355 }
356 
tng__H264ES_process_misc_hrd_param(context_ENC_p ctx,object_buffer_p obj_buffer)357 static VAStatus tng__H264ES_process_misc_hrd_param(context_ENC_p ctx, object_buffer_p obj_buffer)
358 {
359     VAStatus vaStatus = VA_STATUS_SUCCESS;
360     VAEncMiscParameterBuffer *pBuffer = (VAEncMiscParameterBuffer *) obj_buffer->buffer_data;
361     VAEncMiscParameterHRD *psMiscHrdParams = NULL;
362     IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
363     ASSERT(obj_buffer->type == VAEncMiscParameterTypeHRD);
364     ASSERT(obj_buffer->size == sizeof(VAEncMiscParameterHRD));
365     psMiscHrdParams = (VAEncMiscParameterHRD *)pBuffer->data;
366 
367     if (psMiscHrdParams->buffer_size == 0
368 	|| psMiscHrdParams->initial_buffer_fullness == 0) {
369 	drv_debug_msg(VIDEO_DEBUG_ERROR, "Find zero value for buffer_size "
370 		"and initial_buffer_fullness.\n");
371 	vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
372 	return vaStatus;
373     }
374 
375     if (ctx->initial_buffer_fullness > ctx->buffer_size) {
376 	drv_debug_msg(VIDEO_DEBUG_ERROR, "initial_buffer_fullnessi(%d) shouldn't be"
377 		" larger that buffer_size(%d)!\n",
378 		psMiscHrdParams->initial_buffer_fullness,
379 		psMiscHrdParams->buffer_size);
380 	vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
381 	return vaStatus;
382     }
383 
384     if (!psRCParams->bRCEnable) {
385 	drv_debug_msg(VIDEO_DEBUG_ERROR, "Only when rate control is enabled,"
386 		" VAEncMiscParameterTypeHRD will take effect.\n");
387 	vaStatus = VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
388 	return vaStatus;
389     }
390 
391     ctx->buffer_size = psMiscHrdParams->buffer_size;
392     ctx->initial_buffer_fullness = psMiscHrdParams->initial_buffer_fullness;
393     ctx->bInsertHRDParams = IMG_TRUE;
394     drv_debug_msg(VIDEO_DEBUG_GENERAL, "hrd param buffer_size set to %d "
395 	"initial buffer fullness set to %d\n",
396 	ctx->buffer_size, ctx->initial_buffer_fullness);
397 
398     return VA_STATUS_SUCCESS;
399 }
400 
401 //APP_SetVideoParams
tng__H264ES_process_misc_air_param(context_ENC_p ctx,object_buffer_p obj_buffer)402 static VAStatus tng__H264ES_process_misc_air_param(context_ENC_p ctx, object_buffer_p obj_buffer)
403 {
404     VAEncMiscParameterBuffer *pBuffer = (VAEncMiscParameterBuffer *) obj_buffer->buffer_data;
405     VAEncMiscParameterAIR *psMiscAirParams = NULL;
406     ADAPTIVE_INTRA_REFRESH_INFO_TYPE *psAIRInfo = &(ctx->sAirInfo);
407     IMG_UINT32 ui32MbNum;
408     ASSERT(obj_buffer->type == VAEncMiscParameterTypeAIR);
409     ASSERT(obj_buffer->size == sizeof(VAEncMiscParameterAIR));
410 
411     psMiscAirParams = (VAEncMiscParameterAIR*)pBuffer->data;
412     ui32MbNum = (ctx->ui16PictureHeight * ctx->ui16Width) >> 8;
413 
414     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: enable_AIR = %d, mb_num = %d, thresh_hold = %d, air_auto = %d\n", __FUNCTION__,
415         ctx->bEnableAIR, psMiscAirParams->air_num_mbs, psMiscAirParams->air_threshold, psMiscAirParams->air_auto);
416 
417     ctx->bEnableAIR = 1;
418     ctx->bEnableInpCtrl = 1;
419     ctx->bEnableHostBias = 1;
420     ctx->ui8EnableSelStatsFlags |= ESF_FIRST_STAGE_STATS;
421     ctx->ui8EnableSelStatsFlags |= ESF_MP_BEST_MB_DECISION_STATS;
422 
423     /*FIXME
424     if (psMiscAirParams->air_threshold == -1 && psMiscAirParams->air_num_mbs == 0) {
425         drv_debug_msg(VIDEO_DEBUG_ERROR,
426             "%s: ERROR: Cannot have both -AIRMBperFrame set to zero"
427             "AND and -AIRSADThreshold set to -1 (APP_SetVideoParams)\n",
428             __FUNCTION__);
429         return VA_STATUS_ERROR_INVALID_PARAMETER;
430     }*/
431 
432     if (psMiscAirParams->air_num_mbs > 65535) {
433         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: ERROR: air_num_mbs = %d should not bigger than 65536\n",
434             __FUNCTION__, psMiscAirParams->air_num_mbs);
435         return VA_STATUS_ERROR_INVALID_PARAMETER;
436     }
437 
438     if (psMiscAirParams->air_num_mbs > ui32MbNum)
439         psMiscAirParams->air_num_mbs = ui32MbNum;
440 
441     if (psMiscAirParams->air_threshold > 65535) {
442         drv_debug_msg(VIDEO_DEBUG_ERROR,
443             "%s: ERROR: air_threshold = %d should not bigger than 65536\n",
444             __FUNCTION__, psMiscAirParams->air_threshold);
445         return VA_STATUS_ERROR_INVALID_PARAMETER;
446     }
447 
448     if (psMiscAirParams->air_auto) {
449 	psAIRInfo->i32NumAIRSPerFrame = -1;
450 	psAIRInfo->i32SAD_Threshold = -1;
451 	psAIRInfo->i16AIRSkipCnt = -1;
452     } else {
453 	psAIRInfo->i32NumAIRSPerFrame = psMiscAirParams->air_num_mbs;
454 	psAIRInfo->i32SAD_Threshold = psMiscAirParams->air_threshold;
455 	psAIRInfo->i16AIRSkipCnt = -1;
456     }
457 
458     psAIRInfo->ui16AIRScanPos = 0;
459 
460     drv_debug_msg(VIDEO_DEBUG_GENERAL,
461         "%s: air slice size changed to num_air_mbs %d "
462         "air_threshold %d, air_auto %d\n", __FUNCTION__,
463         psMiscAirParams->air_num_mbs, psMiscAirParams->air_threshold,
464         psMiscAirParams->air_auto);
465 
466     if (psAIRInfo->pi8AIR_Table != NULL)
467         free(psAIRInfo->pi8AIR_Table);
468     tng_air_buf_create(ctx);
469 
470     return VA_STATUS_SUCCESS;
471 }
472 
tng__H264ES_process_misc_cir_param(context_ENC_p ctx,object_buffer_p obj_buffer)473 static VAStatus tng__H264ES_process_misc_cir_param(context_ENC_p ctx, object_buffer_p obj_buffer)
474 {
475     VAEncMiscParameterBuffer *pBuffer = (VAEncMiscParameterBuffer *)obj_buffer->buffer_data;
476     VAEncMiscParameterCIR *psMiscCirParams = NULL;
477 
478     ASSERT(obj_buffer->type == VAEncMiscParameterTypeCIR);
479     ASSERT(obj_buffer->size == sizeof(VAEncMiscParameterCIR));
480 
481     psMiscCirParams = (VAEncMiscParameterCIR*)pBuffer->data;
482 
483     if (psMiscCirParams->cir_num_mbs > 0) {
484 	drv_debug_msg(VIDEO_DEBUG_GENERAL,
485 	    "CIR enabled with MB count %d\n", ctx->ui16IntraRefresh);
486 	ctx->ui16IntraRefresh = psMiscCirParams->cir_num_mbs;
487 	ctx->bEnableCIR = 1;
488 	ctx->bEnableInpCtrl = 1;
489 	ctx->bEnableHostBias = 1;
490     } else {
491         drv_debug_msg(VIDEO_DEBUG_ERROR,
492             "%s: ERROR: invalid cir num mbs(%d), should bigger than 0\n",
493             __FUNCTION__, ctx->ui16IntraRefresh);
494         return VA_STATUS_ERROR_INVALID_PARAMETER;
495     }
496 
497     return VA_STATUS_SUCCESS;
498 }
499 
tng__H264ES_calculate_level(context_ENC_p ctx)500 static IMG_UINT8 tng__H264ES_calculate_level(context_ENC_p ctx)
501 {
502     IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
503     IMG_UINT32 ui32MBf=0;
504     IMG_UINT32 ui32MBs;
505     IMG_UINT32 ui32Level=0;
506     IMG_UINT32 ui32TempLevel=0;
507     IMG_UINT32 ui32DpbMbs;
508     // We need to calculate the level based on a few constraints these are
509     // Macroblocks per second
510     // picture size
511     // decoded picture buffer size, and bitrate
512     ui32MBf = (ctx->ui16Width)*(ctx->ui16FrameHeight) >> 8;
513     ui32MBs = ui32MBf * psRCParams->ui32FrameRate;
514 
515 
516     // could do these in nice tables, but this is clearer
517     if      (ui32MBf > 22080) ui32Level = SH_LEVEL_51;
518     else if (ui32MBf >  8704) ui32Level = SH_LEVEL_50;
519     else if (ui32MBf >  8192) ui32Level = SH_LEVEL_42;
520     else if (ui32MBf >  5120) ui32Level = SH_LEVEL_40;
521     else if (ui32MBf >  3600) ui32Level = SH_LEVEL_32;
522     else if (ui32MBf >  1620) ui32Level = SH_LEVEL_31;
523     else if (ui32MBf >   792) ui32Level = SH_LEVEL_22;
524     else if (ui32MBf >   396) ui32Level = SH_LEVEL_21;
525     else if (ui32MBf >    99) ui32Level = SH_LEVEL_11;
526     else ui32Level = SH_LEVEL_10;
527 
528     drv_debug_msg(VIDEO_DEBUG_GENERAL,
529         "%s: ui32MBf = %d, ui32MBs = %d, ui32Level = %d\n",
530         __FUNCTION__, ui32MBf, ui32MBs, ui32Level);
531 
532     //ui32DpbMbs = ui32MBf * (psContext->ui32MaxNumRefFrames + 1);
533     ui32DpbMbs = ui32MBf * (ctx->ui8MaxNumRefFrames + 1);
534 
535     if      (ui32DpbMbs > 110400) ui32TempLevel = SH_LEVEL_51;
536     else if (ui32DpbMbs >  34816) ui32TempLevel = SH_LEVEL_50;
537     else if (ui32DpbMbs >  32768) ui32TempLevel = SH_LEVEL_42;
538     else if (ui32DpbMbs >  20480) ui32TempLevel = SH_LEVEL_40;
539     else if (ui32DpbMbs >  18000) ui32TempLevel = SH_LEVEL_32;
540     else if (ui32DpbMbs >   8100) ui32TempLevel = SH_LEVEL_31;
541     else if (ui32DpbMbs >   4752) ui32TempLevel = SH_LEVEL_22;
542     else if (ui32DpbMbs >   2376) ui32TempLevel = SH_LEVEL_21;
543     else if (ui32DpbMbs >    900) ui32TempLevel = SH_LEVEL_12;
544     else if (ui32DpbMbs >    396) ui32TempLevel = SH_LEVEL_11;
545     else ui32TempLevel = SH_LEVEL_10;
546     ui32Level = tng__max(ui32Level, ui32TempLevel);
547 
548     drv_debug_msg(VIDEO_DEBUG_GENERAL,
549         "%s: ui32DpbMbs = %d, ui32Level = %d\n",
550         __FUNCTION__, ui32DpbMbs, ui32Level);
551 
552     // now restrict based on the number of macroblocks per second
553     if      (ui32MBs > 589824) ui32TempLevel = SH_LEVEL_51;
554     else if (ui32MBs > 522240) ui32TempLevel = SH_LEVEL_50;
555     else if (ui32MBs > 245760) ui32TempLevel = SH_LEVEL_42;
556     else if (ui32MBs > 216000) ui32TempLevel = SH_LEVEL_40;
557     else if (ui32MBs > 108000) ui32TempLevel = SH_LEVEL_32;
558     else if (ui32MBs >  40500) ui32TempLevel = SH_LEVEL_31;
559     else if (ui32MBs >  20250) ui32TempLevel = SH_LEVEL_30;
560     else if (ui32MBs >  19800) ui32TempLevel = SH_LEVEL_22;
561     else if (ui32MBs >  11880) ui32TempLevel = SH_LEVEL_21;
562     else if (ui32MBs >   6000) ui32TempLevel = SH_LEVEL_13;
563     else if (ui32MBs >   3000) ui32TempLevel = SH_LEVEL_12;
564     else if (ui32MBs >   1485) ui32TempLevel = SH_LEVEL_11;
565     else ui32TempLevel = SH_LEVEL_10;
566     ui32Level = tng__max(ui32Level, ui32TempLevel);
567 
568     drv_debug_msg(VIDEO_DEBUG_GENERAL,
569         "%s: ui32TempLevel = %d, ui32Level = %d\n",
570         __FUNCTION__, ui32TempLevel, ui32Level);
571 
572     if (psRCParams->bRCEnable) {
573         // now restrict based on the requested bitrate
574         if      (psRCParams->ui32FrameRate > 135000000) ui32TempLevel = SH_LEVEL_51;
575         else if (psRCParams->ui32FrameRate >  50000000) ui32TempLevel = SH_LEVEL_50;
576         else if (psRCParams->ui32FrameRate >  20000000) ui32TempLevel = SH_LEVEL_41;
577         else if (psRCParams->ui32FrameRate >  14000000) ui32TempLevel = SH_LEVEL_32;
578         else if (psRCParams->ui32FrameRate >  10000000) ui32TempLevel = SH_LEVEL_31;
579         else if (psRCParams->ui32FrameRate >   4000000) ui32TempLevel = SH_LEVEL_30;
580         else if (psRCParams->ui32FrameRate >   2000000) ui32TempLevel = SH_LEVEL_21;
581         else if (psRCParams->ui32FrameRate >    768000) ui32TempLevel = SH_LEVEL_20;
582         else if (psRCParams->ui32FrameRate >    384000) ui32TempLevel = SH_LEVEL_13;
583         else if (psRCParams->ui32FrameRate >    192000) ui32TempLevel = SH_LEVEL_12;
584         else if (psRCParams->ui32FrameRate >    128000) ui32TempLevel = SH_LEVEL_11;
585         else if (psRCParams->ui32FrameRate >     64000) ui32TempLevel = SH_LEVEL_1B;
586         else ui32TempLevel = SH_LEVEL_10;
587 
588         ui32Level = tng__max(ui32Level, ui32TempLevel);
589     }
590 /*
591     if (pParams->bLossless) {
592         ui32Level = tng__max(ui32Level, 320);
593     }
594 */
595     drv_debug_msg(VIDEO_DEBUG_GENERAL,
596         "%s: target level is %d, input level is %d\n",
597         __FUNCTION__, ui32Level, ctx->ui8LevelIdc);
598     return (IMG_UINT8)ui32Level;
599 }
600 
tng__H264ES_process_sequence_param(context_ENC_p ctx,object_buffer_p obj_buffer)601 static VAStatus tng__H264ES_process_sequence_param(context_ENC_p ctx, object_buffer_p obj_buffer)
602 {
603     VAStatus vaStatus = VA_STATUS_SUCCESS;
604     VAEncSequenceParameterBufferH264 *psSeqParams;
605     H264_CROP_PARAMS* psCropParams = &(ctx->sCropParams);
606     IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
607     FRAME_ORDER_INFO *psFrameInfo = &(ctx->sFrameOrderInfo);
608     H264_VUI_PARAMS *psVuiParams = &(ctx->sVuiParams);
609     IMG_UINT32 ui32MaxUnit32 = (IMG_UINT32)0x7ffa;
610     IMG_UINT32 ui32IPCount = 0;
611     IMG_UINT64 ui64Temp = 0;
612 
613     ASSERT(obj_buffer->type == VAEncSequenceParameterBufferType);
614     ASSERT(obj_buffer->size == sizeof(VAEncSequenceParameterBufferH264));
615 
616     if (obj_buffer->size != sizeof(VAEncSequenceParameterBufferH264)) {
617         vaStatus = VA_STATUS_ERROR_UNKNOWN;
618         goto out1;
619     }
620 
621     ctx->obj_context->frame_count = 0;
622     psSeqParams = (VAEncSequenceParameterBufferH264 *) obj_buffer->buffer_data;
623     obj_buffer->buffer_data = NULL;
624     obj_buffer->size = 0;
625 
626 #ifdef _TOPAZHP_PDUMP_
627     tng_H264ES_trace_seq_params(psSeqParams);
628 #endif
629 
630     ctx->ui8LevelIdc = psSeqParams->level_idc;
631     ctx->ui8MaxNumRefFrames = psSeqParams->max_num_ref_frames;
632 
633     ctx->ui32IdrPeriod = psSeqParams->intra_idr_period;
634     ctx->ui32IntraCnt = psSeqParams->intra_period;
635     ui32IPCount = (IMG_UINT32)(psSeqParams->ip_period);
636 
637     if ((ui32IPCount > 4) || (ui32IPCount == 0)) {
638         drv_debug_msg(VIDEO_DEBUG_ERROR,
639             "%s: ip_period %d, it should be in [1, 4]\n",
640             __FUNCTION__, psSeqParams->ip_period);
641         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
642         goto out1;
643     }
644 
645     if (ctx->ui32IntraCnt == 0) {
646         if (ui32IPCount == 1)
647             ctx->ui32IntraCnt = INT_MAX;
648         else
649             ctx->ui32IntraCnt = INT_MAX - (INT_MAX % ui32IPCount);
650         ctx->ui32IdrPeriod = 1;
651     } else if (ctx->ui32IntraCnt == 1) {
652         //only I frame or IDR frames;
653         ui32IPCount = 1;
654         if (ctx->ui32IdrPeriod == 0)
655             ctx->ui32IdrPeriod = INT_MAX;
656     } else {
657         if (ctx->ui32IdrPeriod == 0) {
658             ctx->ui32IdrPeriod = INT_MAX / ctx->ui32IntraCnt;
659         } else if (ctx->ui32IdrPeriod > 1) {
660             ui64Temp = (IMG_UINT64)(ctx->ui32IdrPeriod) * (IMG_UINT64)(ctx->ui32IntraCnt);
661             if (ui64Temp >= (IMG_UINT64)INT_MAX) {
662                 ctx->ui32IdrPeriod = INT_MAX / ctx->ui32IntraCnt;
663             }
664         }
665 
666         if ((ctx->ui32IntraCnt % ui32IPCount) != 0) {
667             if (ctx->ui32IntraCnt > INT_MAX - ui32IPCount + (ctx->ui32IntraCnt % ui32IPCount))
668                 ctx->ui32IntraCnt = INT_MAX - ui32IPCount + (ctx->ui32IntraCnt % ui32IPCount);
669             else
670                 ctx->ui32IntraCnt += ui32IPCount - (ctx->ui32IntraCnt % ui32IPCount);
671         }
672     }
673 
674     if (ctx->ui32FrameCount[ctx->ui32StreamID] > 0) {
675         ctx->idr_force_flag = 1;
676 	if (ctx->ui32IntraCntSave != ctx->ui32IntraCnt) {
677 	    drv_debug_msg(VIDEO_DEBUG_GENERAL,
678 		"%s: intra_period updated from %d to %d\n",
679 		__FUNCTION__, ctx->ui32IntraCntSave, ctx->ui32IntraCnt);
680 	    ctx->rc_update_flag |= RC_MASK_intra_period;
681 	}
682     }
683 
684     ctx->ui32IntraCntSave = ctx->ui32IntraCnt;
685 
686     ctx->ui8SlotsInUse = ui32IPCount + 1; //Bframes + 2
687 
688     //bits per second
689     if (!psSeqParams->bits_per_second) {
690         psSeqParams->bits_per_second = ctx->ui16Width * ctx->ui16PictureHeight * 30 * 12;
691     }
692 
693     if (psSeqParams->bits_per_second > TOPAZ_H264_MAX_BITRATE) {
694         psSeqParams->bits_per_second = TOPAZ_H264_MAX_BITRATE;
695         drv_debug_msg(VIDEO_DEBUG_ERROR,
696             "%s: bits_per_second(%d) exceeds the maximum bitrate, set it with %d\n",
697             __FUNCTION__, psSeqParams->bits_per_second,
698             TOPAZ_H264_MAX_BITRATE);
699     }
700 
701     if (psRCParams->ui32BitsPerSecond == 0)
702         psRCParams->ui32BitsPerSecond = psSeqParams->bits_per_second;
703 
704     if (psSeqParams->bits_per_second != psRCParams->ui32BitsPerSecond) {
705         psRCParams->ui32BitsPerSecond = psSeqParams->bits_per_second;
706 	ctx->rc_update_flag |= RC_MASK_bits_per_second;
707     }
708 
709     psRCParams->ui32IntraFreq = ctx->ui32IntraCnt;
710     psRCParams->ui32TransferBitsPerSecond = psRCParams->ui32BitsPerSecond;
711     psRCParams->ui16BFrames = ui32IPCount - 1;
712 
713     if (psRCParams->ui32FrameRate == 0)
714         psRCParams->ui32FrameRate = 30;
715 
716     //set the B frames
717     if (psRCParams->eRCMode == IMG_RCMODE_VCM)
718         psRCParams->ui16BFrames = 0;
719 
720     if ((psRCParams->ui16BFrames > 0) && (ctx->ui8ProfileIdc == H264ES_PROFILE_BASELINE)) {
721         ctx->ui8ProfileIdc = H264ES_PROFILE_MAIN;
722     }
723 
724     if (psFrameInfo->slot_consume_dpy_order != NULL)
725         free(psFrameInfo->slot_consume_dpy_order);
726     if (psFrameInfo->slot_consume_enc_order != NULL)
727         free(psFrameInfo->slot_consume_enc_order);
728 
729     if (psRCParams->ui16BFrames != 0) {
730         memset(psFrameInfo, 0, sizeof(FRAME_ORDER_INFO));
731         psFrameInfo->slot_consume_dpy_order = (int *)malloc(ctx->ui8SlotsInUse * sizeof(int));
732         psFrameInfo->slot_consume_enc_order = (int *)malloc(ctx->ui8SlotsInUse * sizeof(int));
733 
734         if ((psFrameInfo->slot_consume_dpy_order == NULL) ||
735             (psFrameInfo->slot_consume_enc_order == NULL)) {
736             drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: error malloc slot order array\n", __FUNCTION__);
737         }
738     }
739 
740     //set the crop parameters
741     psCropParams->bClip = psSeqParams->frame_cropping_flag;
742     psCropParams->ui16LeftCropOffset = psSeqParams->frame_crop_left_offset;
743     psCropParams->ui16RightCropOffset = psSeqParams->frame_crop_right_offset;
744     psCropParams->ui16TopCropOffset = psSeqParams->frame_crop_top_offset;
745     psCropParams->ui16BottomCropOffset = psSeqParams->frame_crop_bottom_offset;
746 
747     //set level idc parameter
748     ctx->ui32VertMVLimit = 255 ;//(63.75 in qpel increments)
749     ctx->bLimitNumVectors = IMG_FALSE;
750 
751     if (ctx->ui8LevelIdc == 111)
752         ctx->ui8LevelIdc = SH_LEVEL_1B;
753 
754     ctx->ui8LevelIdc = tng__H264ES_calculate_level(ctx);
755 
756     /*Setting VertMVLimit and LimitNumVectors only for H264*/
757     if (ctx->ui8LevelIdc >= SH_LEVEL_30)
758         ctx->bLimitNumVectors = IMG_TRUE;
759     else
760         ctx->bLimitNumVectors = IMG_FALSE;
761 
762     if (ctx->ui8LevelIdc >= SH_LEVEL_31)
763         ctx->ui32VertMVLimit = 2047 ;//(511.75 in qpel increments)
764     else if (ctx->ui8LevelIdc >= SH_LEVEL_21)
765         ctx->ui32VertMVLimit = 1023 ;//(255.75 in qpel increments)
766     else if (ctx->ui8LevelIdc >= SH_LEVEL_11)
767         ctx->ui32VertMVLimit = 511 ;//(127.75 in qpel increments)
768 
769     //set VUI info
770     memset(psVuiParams, 0, sizeof(H264_VUI_PARAMS));
771     if (psSeqParams->time_scale != 0 && psSeqParams->num_units_in_tick != 0
772 		&& (psSeqParams->time_scale > psSeqParams->num_units_in_tick)) {
773         psVuiParams->Time_Scale = psSeqParams->time_scale;
774         psVuiParams->num_units_in_tick = psSeqParams->num_units_in_tick;
775     }
776 
777 out1:
778     free(obj_buffer->buffer_data);
779     obj_buffer->buffer_data = NULL;
780     obj_buffer->size = 0;
781 
782     return vaStatus;
783 }
784 
785 #if 0
786 static VAStatus tng__H264ES_process_picture_param(context_ENC_p ctx, object_buffer_p obj_buffer)
787 {
788     VAStatus vaStatus = VA_STATUS_SUCCESS;
789     context_ENC_mem *ps_mem = &(ctx->ctx_mem[ctx->ui32StreamID]);
790     context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf[ctx->ui32StreamID]);
791     IMG_RC_PARAMS * psRCParams = &(ctx->sRCParams);
792     VAEncPictureParameterBufferH264 *psPicParams;
793     IMG_BOOL bDepViewPPS = IMG_FALSE;
794 
795     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: start\n",__FUNCTION__);
796     ASSERT(obj_buffer->type == VAEncPictureParameterBufferType);
797     if (obj_buffer->size != sizeof(VAEncPictureParameterBufferH264)) {
798         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s L%d Invalid coded buffer handle\n", __FUNCTION__, __LINE__);
799         return VA_STATUS_ERROR_UNKNOWN;
800     }
801 
802     /* Transfer ownership of VAEncPictureParameterBufferH264 data */
803     psPicParams = (VAEncPictureParameterBufferH264 *) obj_buffer->buffer_data;
804 
805     obj_buffer->buffer_data = NULL;
806     obj_buffer->size = 0;
807 
808     ASSERT(ctx->ui16Width == psPicParams->picture_width);
809     ASSERT(ctx->ui16PictureHeight == psPicParams->picture_height);
810 
811 #ifdef _TOPAZHP_OLD_LIBVA_
812     ps_buf->ref_surface = SURFACE(psPicParams->ReferenceFrames[0].picture_id);
813     ps_buf->coded_buf = BUFFER(psPicParams->coded_buf);
814 #else
815     {
816         IMG_INT32 i;
817         ps_buf->rec_surface = SURFACE(psPicParams->CurrPic.picture_id);
818         for (i = 0; i < 16; i++)
819             ps_buf->ref_surface[i] = SURFACE(psPicParams->ReferenceFrames[i].picture_id);
820         ps_buf->coded_buf = BUFFER(psPicParams->coded_buf);
821     }
822 #endif
823 
824     if (NULL == ps_buf->coded_buf) {
825         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s L%d Invalid coded buffer handle\n", __FUNCTION__, __LINE__);
826         free(psPicParams);
827         return VA_STATUS_ERROR_INVALID_BUFFER;
828     }
829 
830     if ((ctx->bEnableMvc) && (ctx->ui16MVCViewIdx != 0) &&
831         (ctx->ui16MVCViewIdx != (IMG_UINT16)(NON_MVC_VIEW))) {
832         bDepViewPPS = IMG_TRUE;
833     }
834 
835     /************* init ****************
836     ctx->bCabacEnabled = psPicParams->pic_fields.bits.entropy_coding_mode_flag;
837     ctx->bH2648x8Transform = psPicParams->pic_fields.bits.transform_8x8_mode_flag;
838     ctx->bH264IntraConstrained = psPicParams->pic_fields.bits.constrained_intra_pred_flag;
839     ctx->bWeightedPrediction = psPicParams->pic_fields.bits.weighted_pred_flag;
840     ctx->ui8VPWeightedImplicitBiPred = psPicParams->pic_fields.bits.weighted_bipred_idc;
841     ctx->bCustomScaling = psPicParams->pic_fields.bits.pic_scaling_matrix_present_flag;
842     ************* set rc params *************/
843 //    ctx->sRCParams.ui32InitialQp = psPicParams->pic_init_qp;
844 //    ctx->sRCParams.i8QCPOffset = psPicParams->chroma_qp_index_offset;
845     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s psRCParams->ui32InitialQp = %d, psRCParams->iMinQP = %d\n", __FUNCTION__, psPicParams->pic_init_qp, psPicParams->chroma_qp_index_offset);
846     tng__H264ES_prepare_picture_header(
847         ps_mem->bufs_pic_template.virtual_addr,
848         0, //IMG_BOOL    bCabacEnabled,
849         ctx->bH2648x8Transform, //IMG_BOOL    b_8x8transform,
850         0, //IMG_BOOL    bIntraConstrained,
851         0, //IMG_INT8    i8CQPOffset,
852         0, //IMG_BOOL    bWeightedPrediction,
853         0, //IMG_UINT8   ui8WeightedBiPred,
854         0, //IMG_BOOL    bMvcPPS,
855         0, //IMG_BOOL    bScalingMatrix,
856         0  //IMG_BOOL    bScalingLists
857     );
858     free(psPicParams);
859 /*
860     if (psRCParams->ui16BFrames == 0) {
861         tng_send_codedbuf(ctx, (ctx->obj_context->frame_count&1));
862         tng_send_source_frame(ctx, (ctx->obj_context->frame_count&1), ctx->obj_context->frame_count);
863     } else
864         tng__H264ES_provide_buffer_for_BFrames(ctx);
865 */
866     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: end\n",__FUNCTION__);
867 
868     return vaStatus;
869 }
870 #endif
871 
tng__H264ES_process_picture_param_base(context_ENC_p ctx,unsigned char * buf)872 static VAStatus tng__H264ES_process_picture_param_base(context_ENC_p ctx, unsigned char *buf)
873 {
874     VAStatus vaStatus = VA_STATUS_SUCCESS;
875     context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
876     VAEncPictureParameterBufferH264 *psPicParams;
877 #ifndef _TNG_FRAMES_
878     IMG_INT32 i;
879 #endif
880     psPicParams = (VAEncPictureParameterBufferH264 *) buf;
881 
882 #ifdef _TOPAZHP_PDUMP_
883     tng_H264ES_trace_pic_params(psPicParams);
884 #endif
885 
886 #ifdef _TNG_FRAMES_
887     ps_buf->rec_surface  = SURFACE(psPicParams->CurrPic.picture_id);
888     ps_buf->ref_surface  = SURFACE(psPicParams->ReferenceFrames[0].picture_id);
889     ps_buf->ref_surface1 = SURFACE(psPicParams->ReferenceFrames[1].picture_id);
890     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: psPicParams->coded_buf = 0x%08x, ps_buf->coded_buf = 0x%08x\n",
891         __FUNCTION__, psPicParams->coded_buf, ps_buf->coded_buf);
892 #else
893     {
894         ps_buf->rec_surface = SURFACE(psPicParams->CurrPic.picture_id);
895         for (i = 0; i < 4; i++) {
896             ps_buf->ref_surface[i] = SURFACE(psPicParams->ReferenceFrames[i].picture_id);
897 	    ps_buf->ref_surface[i]->is_ref_surface = 1;
898 	}
899     }
900 #endif
901 
902     ps_buf->coded_buf = BUFFER(psPicParams->coded_buf);
903 
904     if (NULL == ps_buf->coded_buf) {
905         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s L%d Invalid coded buffer handle\n", __FUNCTION__, __LINE__);
906         free(psPicParams);
907         return VA_STATUS_ERROR_INVALID_BUFFER;
908     }
909 
910     ctx->bH2648x8Transform = psPicParams->pic_fields.bits.transform_8x8_mode_flag;
911     if ((ctx->bH2648x8Transform == 1) && (ctx->ui8ProfileIdc != H264ES_PROFILE_HIGH)) {
912         drv_debug_msg(VIDEO_DEBUG_ERROR,
913         "%s L%d only high profile could set bH2648x8Transform TRUE\n",
914         __FUNCTION__, __LINE__);
915         ctx->bH2648x8Transform = 0;
916     }
917 
918     ctx->bH264IntraConstrained = psPicParams->pic_fields.bits.constrained_intra_pred_flag;
919     if (ctx->bEnableMVC == 1) {
920         drv_debug_msg(VIDEO_DEBUG_ERROR,
921             "%s L%d MVC could not set bH264IntraConstrained TRUE\n",
922             __FUNCTION__, __LINE__);
923         ctx->bH264IntraConstrained = 0;
924     }
925 
926     ctx->bCabacEnabled = psPicParams->pic_fields.bits.entropy_coding_mode_flag;
927     ctx->bWeightedPrediction = psPicParams->pic_fields.bits.weighted_pred_flag;
928     ctx->ui8VPWeightedImplicitBiPred = psPicParams->pic_fields.bits.weighted_bipred_idc;
929 
930     /************* init ****************
931     ctx->bCustomScaling = psPicParams->pic_fields.bits.pic_scaling_matrix_present_flag;
932     ************* set rc params *************/
933     if (ctx->sRCParams.ui32InitialQp == 0)
934         ctx->sRCParams.ui32InitialQp = psPicParams->pic_init_qp;
935 
936     ctx->ui32LastPicture = psPicParams->last_picture;
937 
938     return vaStatus;
939 }
940 
tng__H264ES_process_picture_param_mvc(context_ENC_p ctx,unsigned char * buf)941 static VAStatus tng__H264ES_process_picture_param_mvc(context_ENC_p ctx, unsigned char *buf)
942 {
943     VAStatus vaStatus = VA_STATUS_SUCCESS;
944     VAEncPictureParameterBufferH264_MVC *psPicMvcParams;
945 
946     psPicMvcParams = (VAEncPictureParameterBufferH264_MVC *) buf;
947     ctx->ui16MVCViewIdx = ctx->ui32StreamID = psPicMvcParams->view_id;
948     //vaStatus = tng__H264ES_process_picture_param_base(ctx, (unsigned char*)&(psPicMvcParams->base_picture_param));
949 
950     return vaStatus;
951 }
952 
tng__H264ES_process_picture_param(context_ENC_p ctx,object_buffer_p obj_buffer)953 static VAStatus tng__H264ES_process_picture_param(context_ENC_p ctx, object_buffer_p obj_buffer)
954 {
955     VAStatus vaStatus = VA_STATUS_SUCCESS;
956 
957     ASSERT(obj_buffer->type == VAEncPictureParameterBufferType);
958 
959     drv_debug_msg(VIDEO_DEBUG_GENERAL,
960         "%s: ctx->bEnableMVC = %d\n", __FUNCTION__, ctx->bEnableMVC);
961 
962     if (ctx->bEnableMVC) {
963         if (obj_buffer->size != sizeof(VAEncPictureParameterBufferH264_MVC)) {
964             drv_debug_msg(VIDEO_DEBUG_ERROR,
965                 "%s L%d Invalid picture parameter H264 mvc buffer handle\n",
966                 __FUNCTION__, __LINE__);
967             return VA_STATUS_ERROR_UNKNOWN;
968         }
969         vaStatus = tng__H264ES_process_picture_param_mvc(ctx, obj_buffer->buffer_data);
970     } else {
971         if (obj_buffer->size != sizeof(VAEncPictureParameterBufferH264)) {
972             drv_debug_msg(VIDEO_DEBUG_ERROR,
973                 "%s L%d Invalid picture parameter H264 buffer handle\n",
974                 __FUNCTION__, __LINE__);
975             return VA_STATUS_ERROR_UNKNOWN;
976         }
977         vaStatus = tng__H264ES_process_picture_param_base(ctx, obj_buffer->buffer_data);
978     }
979     free(obj_buffer->buffer_data);
980     obj_buffer->buffer_data = NULL;
981     obj_buffer->size = 0;
982     return vaStatus;
983 }
984 
tng__H264ES_process_slice_param_mrfld(context_ENC_p ctx,object_buffer_p obj_buffer)985 static VAStatus tng__H264ES_process_slice_param_mrfld(context_ENC_p ctx, object_buffer_p obj_buffer)
986 {
987     VAStatus vaStatus = VA_STATUS_SUCCESS;
988     VAEncSliceParameterBufferH264 *psSliceParamsH264;
989     unsigned int i;
990     unsigned int uiPreMBAddress = 0;
991     unsigned int uiCurMBAddress = 0;
992     unsigned int uiPreMBNumbers = 0;
993     unsigned int uiCurMBNumbers = 0;
994     unsigned int uiAllMBNumbers = 0;
995     unsigned char ucPreDeblockIdc = 0;
996     unsigned char ucCurDeblockIdc = 0;
997 
998     /* Transfer ownership of VAEncPictureParameterBufferH264 data */
999     psSliceParamsH264 = (VAEncSliceParameterBufferH264*) obj_buffer->buffer_data;
1000 
1001 #ifdef _TOPAZHP_PDUMP_
1002     tng_H264ES_trace_slice_params(psSliceParamsH264);
1003 #endif
1004 
1005     ucPreDeblockIdc = psSliceParamsH264->disable_deblocking_filter_idc;
1006 
1007     for (i = 0; i < obj_buffer->num_elements; i++) {
1008         uiCurMBAddress = psSliceParamsH264->macroblock_address;
1009         uiCurMBNumbers = psSliceParamsH264->num_macroblocks;
1010         if (uiCurMBAddress != uiPreMBAddress + uiPreMBNumbers) {
1011             drv_debug_msg(VIDEO_DEBUG_ERROR,
1012                 "%s L%d Error Macroblock Address (%d), address (%d), number (%d)\n",
1013                 __FUNCTION__, __LINE__, i, psSliceParamsH264->macroblock_address,
1014                 psSliceParamsH264->num_macroblocks);
1015             return VA_STATUS_ERROR_INVALID_PARAMETER;
1016         }
1017         uiPreMBNumbers = uiCurMBNumbers;
1018         uiPreMBAddress = uiCurMBAddress;
1019         uiAllMBNumbers += uiCurMBNumbers;
1020 
1021         ucCurDeblockIdc = psSliceParamsH264->disable_deblocking_filter_idc;
1022         if (ucPreDeblockIdc != ucCurDeblockIdc) {
1023             drv_debug_msg(VIDEO_DEBUG_ERROR,
1024                 "%s L%d Error Macroblock Address (%d), deblock idc pre (%d), cur (%d)\n",
1025                 __FUNCTION__, __LINE__, i, ucPreDeblockIdc, ucCurDeblockIdc);
1026             return VA_STATUS_ERROR_INVALID_PARAMETER;
1027         }
1028         psSliceParamsH264++;
1029     }
1030 
1031     if (uiAllMBNumbers != (unsigned int)(((IMG_UINT16)(ctx->ui16Width) * (IMG_UINT16)(ctx->ui16PictureHeight)) >> 8)) {
1032         drv_debug_msg(VIDEO_DEBUG_ERROR,
1033             "%s L%d Error Macroblock all number (%d), (%d)\n",
1034             __FUNCTION__, __LINE__, i, uiAllMBNumbers,
1035             ((ctx->ui16Width * ctx->ui16PictureHeight) >> 8));
1036         return VA_STATUS_ERROR_INVALID_PARAMETER;
1037     }
1038 
1039     //deblocking behaviour
1040     ctx->bArbitrarySO = IMG_FALSE;
1041     ctx->ui8DeblockIDC = ucCurDeblockIdc;
1042     ctx->ui8SlicesPerPicture = obj_buffer->num_elements;
1043 
1044     return vaStatus;
1045 }
1046 
tng__H264ES_process_slice_param_mdfld(context_ENC_p ctx,object_buffer_p obj_buffer)1047 static VAStatus tng__H264ES_process_slice_param_mdfld(context_ENC_p ctx, object_buffer_p obj_buffer)
1048 {
1049     VAStatus vaStatus = VA_STATUS_SUCCESS;
1050     VAEncSliceParameterBuffer *psSliceParams = NULL;
1051     psSliceParams = (VAEncSliceParameterBuffer*) obj_buffer->buffer_data;
1052 
1053     //deblocking behaviour
1054     ctx->bArbitrarySO = IMG_FALSE;
1055     ctx->ui8DeblockIDC = psSliceParams->slice_flags.bits.disable_deblocking_filter_idc;
1056     ctx->ui8SlicesPerPicture = obj_buffer->num_elements;
1057     return vaStatus;
1058 }
1059 
tng__H264ES_process_misc_max_slice_size_param(context_ENC_p ctx,object_buffer_p obj_buffer)1060 static VAStatus tng__H264ES_process_misc_max_slice_size_param(context_ENC_p ctx, object_buffer_p obj_buffer)
1061 {
1062     VAEncMiscParameterBuffer *pBuffer = (VAEncMiscParameterBuffer *) obj_buffer->buffer_data;
1063     VAEncMiscParameterMaxSliceSize *psMiscMaxSliceSizeParams = NULL;
1064     IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
1065 
1066     ASSERT(obj_buffer->type == VAEncMiscParameterTypeMaxSliceSize);
1067     ASSERT(obj_buffer->size == sizeof(VAEncMiscParameterMaxSliceSize));
1068 
1069     psMiscMaxSliceSizeParams = (VAEncMiscParameterMaxSliceSize*)pBuffer->data;
1070 
1071     if (psMiscMaxSliceSizeParams->max_slice_size > 0) {
1072 	psRCParams->ui32SliceByteLimit = psMiscMaxSliceSizeParams->max_slice_size;
1073 	drv_debug_msg(VIDEO_DEBUG_GENERAL,
1074 	    "Max slice size is %d\n", psRCParams->ui32SliceByteLimit);
1075     } else {
1076         drv_debug_msg(VIDEO_DEBUG_ERROR,
1077             "%s: ERROR: invalid max slice size(%d), should bigger than 0\n",
1078             __FUNCTION__, psMiscMaxSliceSizeParams->max_slice_size);
1079 	psRCParams->ui32SliceByteLimit = 0;
1080         return VA_STATUS_ERROR_INVALID_PARAMETER;
1081     }
1082 
1083     return VA_STATUS_SUCCESS;
1084 }
1085 
tng__H264ES_process_slice_param(context_ENC_p ctx,object_buffer_p obj_buffer)1086 static VAStatus tng__H264ES_process_slice_param(context_ENC_p ctx, object_buffer_p obj_buffer)
1087 {
1088     VAStatus vaStatus = VA_STATUS_SUCCESS;
1089     ASSERT(obj_buffer->type == VAEncSliceParameterBufferType);
1090     /* Prepare InParams for macros of current slice, insert slice header, insert do slice command */
1091 
1092     if (obj_buffer->size == sizeof(VAEncSliceParameterBufferH264)) {
1093         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Receive VAEncSliceParameterBufferH264 buffer\n");
1094         vaStatus = tng__H264ES_process_slice_param_mrfld(ctx, obj_buffer);
1095     } else if (obj_buffer->size == sizeof(VAEncSliceParameterBuffer)) {
1096         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Receive VAEncSliceParameterBuffer buffer\n");
1097         vaStatus = tng__H264ES_process_slice_param_mdfld(ctx, obj_buffer);
1098     } else {
1099         drv_debug_msg(VIDEO_DEBUG_ERROR, "Buffer size(%d) is wrong. It should be %d or %d\n",
1100             obj_buffer->size, sizeof(VAEncSliceParameterBuffer),
1101             sizeof(VAEncSliceParameterBufferH264));
1102         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
1103     }
1104 
1105     free(obj_buffer->buffer_data);
1106     obj_buffer->size = 0;
1107     obj_buffer->buffer_data = NULL;
1108     return vaStatus;
1109 }
1110 
tng__H264ES_process_misc_param(context_ENC_p ctx,object_buffer_p obj_buffer)1111 static VAStatus tng__H264ES_process_misc_param(context_ENC_p ctx, object_buffer_p obj_buffer)
1112 {
1113     VAStatus vaStatus = VA_STATUS_SUCCESS;
1114     VAEncMiscParameterBuffer *pBuffer;
1115 
1116     ASSERT(obj_buffer->type == VAEncMiscParameterBufferType);
1117     ASSERT(ctx != NULL);
1118     /* Transfer ownership of VAEncMiscParameterBuffer data */
1119     pBuffer = (VAEncMiscParameterBuffer *) obj_buffer->buffer_data;
1120     obj_buffer->size = 0;
1121 
1122     switch (pBuffer->type) {
1123         case VAEncMiscParameterTypeFrameRate:
1124             vaStatus = tng__H264ES_process_misc_framerate_param(ctx, obj_buffer);
1125             break;
1126         case VAEncMiscParameterTypeRateControl:
1127             vaStatus = tng__H264ES_process_misc_ratecontrol_param(ctx, obj_buffer);
1128             break;
1129         case VAEncMiscParameterTypeHRD:
1130             vaStatus = tng__H264ES_process_misc_hrd_param(ctx, obj_buffer);
1131             break;
1132         case VAEncMiscParameterTypeAIR:
1133             vaStatus = tng__H264ES_process_misc_air_param(ctx, obj_buffer);
1134             break;
1135 	case VAEncMiscParameterTypeCIR:
1136             vaStatus = tng__H264ES_process_misc_cir_param(ctx, obj_buffer);
1137             break;
1138 	case VAEncMiscParameterTypeMaxSliceSize:
1139 	    vaStatus = tng__H264ES_process_misc_max_slice_size_param(ctx, obj_buffer);
1140             break;
1141         default:
1142             break;
1143     }
1144     free(obj_buffer->buffer_data);
1145     obj_buffer->buffer_data = NULL;
1146 
1147     return vaStatus;
1148 }
1149 
tng_H264ES_QueryConfigAttributes(VAProfile __maybe_unused profile,VAEntrypoint __maybe_unused entrypoint,VAConfigAttrib * attrib_list,int num_attribs)1150 static void tng_H264ES_QueryConfigAttributes(
1151     VAProfile __maybe_unused profile,
1152     VAEntrypoint __maybe_unused entrypoint,
1153     VAConfigAttrib *attrib_list,
1154     int num_attribs)
1155 {
1156     int i;
1157 
1158     /* RateControl attributes */
1159     for (i = 0; i < num_attribs; i++) {
1160         switch (attrib_list[i].type) {
1161         case VAConfigAttribRTFormat:
1162             break;
1163 
1164         case VAConfigAttribRateControl:
1165             attrib_list[i].value = VA_RC_NONE | VA_RC_CBR | VA_RC_VBR | VA_RC_VCM;
1166             break;
1167 
1168         case VAConfigAttribEncAutoReference:
1169             attrib_list[i].value = 1;
1170             break;
1171 
1172         case VAConfigAttribEncMaxRefFrames:
1173             attrib_list[i].value = 4;
1174             break;
1175 
1176         default:
1177             attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
1178             break;
1179         }
1180     }
1181 }
1182 
tng_H264ES_ValidateConfig(object_config_p obj_config)1183 static VAStatus tng_H264ES_ValidateConfig(
1184     object_config_p obj_config)
1185 {
1186     int i;
1187 
1188     /* Check all attributes */
1189     for (i = 0; i < obj_config->attrib_count; i++) {
1190         switch (obj_config->attrib_list[i].type) {
1191             case VAConfigAttribRTFormat:
1192                 /* Ignore */
1193                 break;
1194             case VAConfigAttribRateControl:
1195                 break;
1196             case VAConfigAttribEncAutoReference:
1197                 break;
1198             case VAConfigAttribEncMaxRefFrames:
1199                 break;
1200             default:
1201                 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
1202         }
1203     }
1204 
1205     return VA_STATUS_SUCCESS;
1206 }
1207 
tng_H264ES_setup_profile_features(context_ENC_p ctx)1208 static VAStatus tng_H264ES_setup_profile_features(context_ENC_p ctx)
1209 {
1210     VAStatus vaStatus = VA_STATUS_SUCCESS;
1211 
1212     IMG_ENCODE_FEATURES * pEncFeatures = &ctx->sEncFeatures;
1213     pEncFeatures->bEnable8x16MVDetect = IMG_TRUE;
1214     pEncFeatures->bEnable16x8MVDetect = IMG_TRUE;
1215 
1216     return vaStatus;
1217 }
1218 
1219 
tng_H264ES_CreateContext(object_context_p obj_context,object_config_p obj_config)1220 static VAStatus tng_H264ES_CreateContext(
1221     object_context_p obj_context,
1222     object_config_p obj_config)
1223 {
1224     VAStatus vaStatus = VA_STATUS_SUCCESS;
1225     context_ENC_p ctx;
1226 
1227     vaStatus = tng_CreateContext(obj_context, obj_config, 0);
1228 
1229     if (VA_STATUS_SUCCESS != vaStatus)
1230         return VA_STATUS_ERROR_ALLOCATION_FAILED;
1231 
1232     ctx = (context_ENC_p) obj_context->format_data;
1233     ctx->eStandard = IMG_STANDARD_H264;
1234 
1235     tng__H264ES_init_context(obj_context, obj_config);
1236 
1237     vaStatus = tng__H264ES_init_profile(obj_context, obj_config);
1238     if (vaStatus != VA_STATUS_SUCCESS) {
1239         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: tng__H264ES_init_profile\n", __FUNCTION__);
1240     }
1241 
1242     vaStatus = tng__H264ES_init_format_mode(obj_context, obj_config);
1243     if (vaStatus != VA_STATUS_SUCCESS) {
1244         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: tng__H264ES_init_format_mode\n", __FUNCTION__);
1245     }
1246 
1247     vaStatus = tng__H264ES_get_codec_type(obj_context, obj_config);
1248     if (vaStatus != VA_STATUS_SUCCESS) {
1249         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: tng__H264ES_init_rc_mode\n", __FUNCTION__);
1250     }
1251 
1252     vaStatus = tng_H264ES_setup_profile_features(ctx);
1253     if (vaStatus != VA_STATUS_SUCCESS) {
1254         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: tng__profile_features\n", __FUNCTION__);
1255     }
1256 
1257     vaStatus = tng__patch_hw_profile(ctx);
1258     if (vaStatus != VA_STATUS_SUCCESS) {
1259         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: tng__patch_hw_profile\n", __FUNCTION__);
1260     }
1261 
1262     return vaStatus;
1263 }
1264 
tng_H264ES_DestroyContext(object_context_p obj_context)1265 static void tng_H264ES_DestroyContext(
1266     object_context_p obj_context)
1267 {
1268     tng_DestroyContext(obj_context, 0);
1269 }
1270 
tng_H264ES_BeginPicture(object_context_p obj_context)1271 static VAStatus tng_H264ES_BeginPicture(
1272     object_context_p obj_context)
1273 {
1274     INIT_CONTEXT_H264ES;
1275     VAStatus vaStatus = VA_STATUS_SUCCESS;
1276     vaStatus = tng_BeginPicture(ctx);
1277     return vaStatus;
1278 }
1279 
tng_H264ES_RenderPicture(object_context_p obj_context,object_buffer_p * buffers,int num_buffers)1280 static VAStatus tng_H264ES_RenderPicture(
1281     object_context_p obj_context,
1282     object_buffer_p *buffers,
1283     int num_buffers)
1284 {
1285     INIT_CONTEXT_H264ES;
1286     VAStatus vaStatus = VA_STATUS_SUCCESS;
1287     int i;
1288 
1289     for (i = 0; i < num_buffers; i++) {
1290         object_buffer_p obj_buffer = buffers[i];
1291         drv_debug_msg(VIDEO_DEBUG_GENERAL,
1292             "%s: type = %d, num = %d\n",
1293             __FUNCTION__, obj_buffer->type, num_buffers);
1294 
1295         switch (obj_buffer->type) {
1296             case VAEncSequenceParameterBufferType:
1297                 drv_debug_msg(VIDEO_DEBUG_GENERAL,
1298                     "tng_H264_RenderPicture got VAEncSequenceParameterBufferType\n");
1299                 vaStatus = tng__H264ES_process_sequence_param(ctx, obj_buffer);
1300                 DEBUG_FAILURE;
1301                 break;
1302             case VAEncPictureParameterBufferType:
1303                 drv_debug_msg(VIDEO_DEBUG_GENERAL,
1304                     "tng_H264_RenderPicture got VAEncPictureParameterBuffer\n");
1305                 vaStatus = tng__H264ES_process_picture_param(ctx, obj_buffer);
1306                 DEBUG_FAILURE;
1307                 break;
1308 
1309             case VAEncSliceParameterBufferType:
1310                 drv_debug_msg(VIDEO_DEBUG_GENERAL,
1311                     "tng_H264_RenderPicture got VAEncSliceParameterBufferType\n");
1312                 vaStatus = tng__H264ES_process_slice_param(ctx, obj_buffer);
1313                 DEBUG_FAILURE;
1314                 break;
1315 
1316             case VAEncMiscParameterBufferType:
1317                 drv_debug_msg(VIDEO_DEBUG_GENERAL,
1318                     "tng_H264_RenderPicture got VAEncMiscParameterBufferType\n");
1319                 vaStatus = tng__H264ES_process_misc_param(ctx, obj_buffer);
1320                 DEBUG_FAILURE;
1321                 break;
1322             default:
1323                 vaStatus = VA_STATUS_ERROR_UNKNOWN;
1324                 DEBUG_FAILURE;
1325         }
1326         if (vaStatus != VA_STATUS_SUCCESS) {
1327             break;
1328         }
1329     }
1330     return vaStatus;
1331 }
1332 
tng_H264ES_EndPicture(object_context_p obj_context)1333 static VAStatus tng_H264ES_EndPicture(
1334     object_context_p obj_context)
1335 {
1336     INIT_CONTEXT_H264ES;
1337     VAStatus vaStatus = VA_STATUS_SUCCESS;
1338     vaStatus = tng_EndPicture(ctx);
1339     return vaStatus;
1340 }
1341 
1342 struct format_vtable_s tng_H264ES_vtable = {
1343 queryConfigAttributes:
1344     tng_H264ES_QueryConfigAttributes,
1345 validateConfig:
1346     tng_H264ES_ValidateConfig,
1347 createContext:
1348     tng_H264ES_CreateContext,
1349 destroyContext:
1350     tng_H264ES_DestroyContext,
1351 beginPicture:
1352     tng_H264ES_BeginPicture,
1353 renderPicture:
1354     tng_H264ES_RenderPicture,
1355 endPicture:
1356     tng_H264ES_EndPicture
1357 };
1358 
1359 /*EOF*/
1360