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