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 * Zhaohan Ren <zhaohan.ren@intel.com>
30 *
31 */
32
33
34 #include <errno.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <stdint.h>
38 #include <string.h>
39
40 #include "psb_def.h"
41 #include "psb_surface.h"
42 #include "tng_cmdbuf.h"
43 #include "tng_hostcode.h"
44 #include "tng_hostheader.h"
45 #include "tng_MPEG4ES.h"
46 #include "psb_drv_debug.h"
47
48 #include "hwdefs/coreflags.h"
49 #include "hwdefs/topaz_vlc_regs.h"
50 #include "hwdefs/topaz_db_regs.h"
51 #include "hwdefs/topazhp_default_params.h"
52
53 #define TOPAZ_MPEG4_MAX_BITRATE 16000000
54
55 #define INIT_CONTEXT_MPEG4ES context_ENC_p ctx = (context_ENC_p) obj_context->format_data
56 #define SURFACE(id) ((object_surface_p) object_heap_lookup( &ctx->obj_context->driver_data->surface_heap, id ))
57 #define BUFFER(id) ((object_buffer_p) object_heap_lookup( &ctx->obj_context->driver_data->buffer_heap, id ))
58
tng_MPEG4ES_QueryConfigAttributes(VAProfile __maybe_unused profile,VAEntrypoint __maybe_unused entrypoint,VAConfigAttrib * attrib_list,int num_attribs)59 static void tng_MPEG4ES_QueryConfigAttributes(
60 VAProfile __maybe_unused profile,
61 VAEntrypoint __maybe_unused entrypoint,
62 VAConfigAttrib *attrib_list,
63 int num_attribs)
64 {
65 int i;
66
67 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s\n", __FUNCTION__);
68
69 /* RateControl attributes */
70 for (i = 0; i < num_attribs; i++) {
71 switch (attrib_list[i].type) {
72 case VAConfigAttribRTFormat:
73 break;
74
75 case VAConfigAttribEncAutoReference:
76 attrib_list[i].value = 1;
77 break;
78
79 case VAConfigAttribEncMaxRefFrames:
80 attrib_list[i].value = 2;
81 break;
82
83 case VAConfigAttribRateControl:
84 attrib_list[i].value = VA_RC_NONE | VA_RC_CBR | VA_RC_VBR;
85 break;
86
87 default:
88 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
89 break;
90 }
91 }
92 }
93
94
tng_MPEG4ES_ValidateConfig(object_config_p obj_config)95 static VAStatus tng_MPEG4ES_ValidateConfig(
96 object_config_p obj_config)
97 {
98 int i;
99 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s\n", __FUNCTION__);
100 /* Check all attributes */
101 for (i = 0; i < obj_config->attrib_count; i++) {
102 switch (obj_config->attrib_list[i].type) {
103 case VAConfigAttribRTFormat:
104 /* Ignore */
105 break;
106 case VAConfigAttribRateControl:
107 break;
108 case VAConfigAttribEncAutoReference:
109 break;
110 case VAConfigAttribEncMaxRefFrames:
111 break;
112 default:
113 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
114 }
115 }
116
117 return VA_STATUS_SUCCESS;
118 }
119
tng_MPEG4ES_CreateContext(object_context_p obj_context,object_config_p obj_config)120 static VAStatus tng_MPEG4ES_CreateContext(
121 object_context_p obj_context,
122 object_config_p obj_config)
123 {
124 VAStatus vaStatus = VA_STATUS_SUCCESS;
125 context_ENC_p ctx;
126 unsigned int eRCMode;
127
128 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s\n", __FUNCTION__);
129
130 vaStatus = tng_CreateContext(obj_context, obj_config, 0);
131
132 if (VA_STATUS_SUCCESS != vaStatus)
133 return VA_STATUS_ERROR_ALLOCATION_FAILED;
134
135 ctx = (context_ENC_p) obj_context->format_data;
136 ctx->eStandard = IMG_STANDARD_MPEG4;
137 ctx->eFormat = IMG_CODEC_PL12; // use default
138
139 switch(ctx->sRCParams.eRCMode) {
140 case IMG_RCMODE_NONE:
141 ctx->eCodec = IMG_CODEC_MPEG4_NO_RC;
142 break;
143 case IMG_RCMODE_VBR:
144 ctx->eCodec = IMG_CODEC_MPEG4_VBR;
145 break;
146 case IMG_RCMODE_CBR:
147 ctx->eCodec = IMG_CODEC_MPEG4_CBR;
148 break;
149 default:
150 drv_debug_msg(VIDEO_DEBUG_ERROR, "Unknown RCMode %08x\n", ctx->sRCParams.eRCMode);
151 break;
152 }
153
154 ctx->bIsInterlaced = IMG_FALSE;
155 ctx->bIsInterleaved = IMG_FALSE;
156 ctx->ui16PictureHeight = ctx->ui16FrameHeight;
157
158 ctx->bVPAdaptiveRoundingDisable = IMG_TRUE;
159
160 /* TopazHP only support Simple Profile */
161 switch (obj_config->profile) {
162 case VAProfileMPEG4Simple:
163 ctx->ui8ProfileIdc = SP;
164 break;
165 default:
166 ctx->ui8ProfileIdc = SP;
167 break;
168 }
169
170 //This parameter need not be exposed
171 ctx->ui8InterIntraIndex = 3;
172 ctx->ui8CodedSkippedIndex = 3;
173 ctx->bEnableHostQP = IMG_FALSE;
174 ctx->uMaxChunks = 0xA0;
175 ctx->uChunksPerMb = 0x40;
176 ctx->uPriorityChunks = (0xA0 - 0x60);
177 ctx->ui32FCode = 4;
178 ctx->iFineYSearchSize = 2;
179
180 //This parameter need not be exposed
181 //host to control the encoding process
182 ctx->bEnableInpCtrl = IMG_FALSE;
183 ctx->bEnableHostBias = IMG_FALSE;
184 //By default false Newly Added
185 ctx->bEnableCumulativeBiases = IMG_FALSE;
186
187 //Weighted Prediction is not supported in TopazHP Version 3.0
188 ctx->bWeightedPrediction = IMG_FALSE;
189 ctx->ui8VPWeightedImplicitBiPred = 0;
190 ctx->bInsertHRDParams = 0;
191
192
193 ctx->bArbitrarySO = IMG_FALSE;
194 ctx->ui32BasicUnit = 0;
195
196 return vaStatus;
197 }
198
tng_MPEG4ES_DestroyContext(object_context_p obj_context)199 static void tng_MPEG4ES_DestroyContext(
200 object_context_p obj_context)
201 {
202 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s\n", __FUNCTION__);
203 tng_DestroyContext(obj_context, 0);
204 }
205
tng_MPEG4ES_BeginPicture(object_context_p obj_context)206 static VAStatus tng_MPEG4ES_BeginPicture(
207 object_context_p obj_context)
208 {
209 INIT_CONTEXT_MPEG4ES;
210 tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
211 context_ENC_mem *ps_mem = &(ctx->ctx_mem[ctx->ui32StreamID]);
212 VAStatus vaStatus = VA_STATUS_SUCCESS;
213 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s start\n", __FUNCTION__);
214 vaStatus = tng_BeginPicture(ctx);
215
216 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s end\n", __FUNCTION__);
217 return vaStatus;
218 }
219
tng__MPEG4ES_process_sequence_param(context_ENC_p ctx,object_buffer_p obj_buffer)220 static VAStatus tng__MPEG4ES_process_sequence_param(context_ENC_p ctx, object_buffer_p obj_buffer)
221 {
222 context_ENC_mem *ps_mem = &(ctx->ctx_mem[ctx->ui32StreamID]);
223 VAEncSequenceParameterBufferMPEG4 *psSeqParams;
224 tng_cmdbuf_p cmdbuf = ctx->obj_context->tng_cmdbuf;
225 IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
226
227 ASSERT(obj_buffer->type == VAEncSequenceParameterBufferType);
228 ASSERT(obj_buffer->size == sizeof(VAEncSequenceParameterBufferMPEG4));
229
230 if (obj_buffer->size != sizeof(VAEncSequenceParameterBufferMPEG4)) {
231 return VA_STATUS_ERROR_UNKNOWN;
232 }
233
234 ctx->obj_context->frame_count = 0;
235 psSeqParams = (VAEncSequenceParameterBufferMPEG4 *) obj_buffer->buffer_data;
236 obj_buffer->buffer_data = NULL;
237 obj_buffer->size = 0;
238
239 ctx->ui32IdrPeriod = psSeqParams->intra_period;
240 ctx->ui32IntraCnt = psSeqParams->intra_period;
241
242 if (ctx->ui32IntraCnt == 0) {
243 ctx->ui32IntraCnt = INT_MAX;
244 ctx->ui32IdrPeriod = 1;
245 drv_debug_msg(VIDEO_DEBUG_GENERAL,
246 "%s: only ONE I frame in the sequence, %d\n",
247 __FUNCTION__, ctx->ui32IdrPeriod);
248 }
249
250 ctx->bCustomScaling = IMG_FALSE;
251 ctx->bUseDefaultScalingList = IMG_FALSE;
252
253 //set MV limit infor
254 ctx->ui32VertMVLimit = 255 ;//(63.75 in qpel increments)
255 ctx->bLimitNumVectors = IMG_TRUE;
256
257 ctx->ui8LevelIdc = psSeqParams->profile_and_level_indication;
258
259 /**************set rc params ****************/
260 if (psSeqParams->bits_per_second > TOPAZ_MPEG4_MAX_BITRATE) {
261 ctx->sRCParams.ui32BitsPerSecond = TOPAZ_MPEG4_MAX_BITRATE;
262 drv_debug_msg(VIDEO_DEBUG_GENERAL, " bits_per_second(%d) exceeds \
263 the maximum bitrate, set it with %d\n",
264 psSeqParams->bits_per_second,
265 TOPAZ_MPEG4_MAX_BITRATE);
266 } else
267 ctx->sRCParams.ui32BitsPerSecond = psSeqParams->bits_per_second;
268
269 //FIXME: Zhaohan, this should be figured out in testsuite?
270 if (!ctx->uiCbrBufferTenths)
271 ctx->uiCbrBufferTenths = TOPAZHP_DEFAULT_uiCbrBufferTenths;
272
273 if (ctx->uiCbrBufferTenths) {
274 psRCParams->ui32BufferSize = (IMG_UINT32)(psRCParams->ui32BitsPerSecond * ctx->uiCbrBufferTenths / 10.0);
275 } else {
276 if (psRCParams->ui32BitsPerSecond < 256000)
277 psRCParams->ui32BufferSize = ((9 * psRCParams->ui32BitsPerSecond) >> 1);
278 else
279 psRCParams->ui32BufferSize = ((5 * psRCParams->ui32BitsPerSecond) >> 1);
280 }
281
282 psRCParams->i32InitialDelay = (13 * psRCParams->ui32BufferSize) >> 4;
283 psRCParams->i32InitialLevel = (3 * psRCParams->ui32BufferSize) >> 4;
284 psRCParams->ui32IntraFreq = psSeqParams->intra_period;
285
286 psRCParams->ui32InitialQp = psSeqParams->initial_qp;
287 psRCParams->iMinQP = psSeqParams->min_qp;
288 ctx->ui32BasicUnit = psSeqParams->min_qp;
289 //psRCParams->ui32BUSize = psSeqParams->basic_unit_size;
290 //ctx->ui32KickSize = psRCParams->ui32BUSize;
291 psRCParams->ui32FrameRate = psSeqParams->frame_rate;
292
293 //B-frames are not supported for non-H.264 streams
294 ctx->sRCParams.ui16BFrames = 0;
295 ctx->ui8SlotsInUse = psRCParams->ui16BFrames + 2;
296
297 #if HEADERS_VERBOSE_OUTPUT
298 drv_debug_msg(VIDEO_DEBUG_GENERAL, "\n\n**********************************************************************\n");
299 drv_debug_msg(VIDEO_DEBUG_GENERAL, "******** HOST FIRMWARE ROUTINES TO PASS HEADERS AND TOKENS TO MTX******\n");
300 drv_debug_msg(VIDEO_DEBUG_GENERAL, "**********************************************************************\n\n");
301 #endif
302
303 free(psSeqParams);
304
305 return VA_STATUS_SUCCESS;
306 }
307
tng__MPEG4ES_process_picture_param(context_ENC_p ctx,object_buffer_p obj_buffer)308 static VAStatus tng__MPEG4ES_process_picture_param(context_ENC_p ctx, object_buffer_p obj_buffer)
309 {
310 VAStatus vaStatus = VA_STATUS_SUCCESS;
311 context_ENC_mem *ps_mem = &(ctx->ctx_mem[ctx->ui32StreamID]);
312 context_ENC_frame_buf *ps_buf = &(ctx->ctx_frame_buf);
313 VAEncPictureParameterBufferMPEG4 *psPicParams;
314 IMG_BOOL bDepViewPPS = IMG_FALSE;
315 void* pTmpBuf = NULL;
316
317 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: start\n",__FUNCTION__);
318 ASSERT(obj_buffer->type == VAEncPictureParameterBufferType);
319 if (obj_buffer->size != sizeof(VAEncPictureParameterBufferMPEG4)) {
320 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s L%d Invalid coded buffer handle\n", __FUNCTION__, __LINE__);
321 return VA_STATUS_ERROR_UNKNOWN;
322 }
323
324 /* Transfer ownership of VAEncPictureParameterBufferMPEG4 data */
325 psPicParams = (VAEncPictureParameterBufferMPEG4 *) obj_buffer->buffer_data;
326 obj_buffer->buffer_data = NULL;
327 obj_buffer->size = 0;
328
329 ASSERT(ctx->ui16Width == psPicParams->picture_width);
330 ASSERT(ctx->ui16PictureHeight == psPicParams->picture_height);
331 #ifndef _TNG_FRAMES_
332 ps_buf->ref_surface[0] = ps_buf->ref_surface[2] = SURFACE(psPicParams->reference_picture);
333 ps_buf->ref_surface[1] = ps_buf->ref_surface[3] = SURFACE(psPicParams->reconstructed_picture);
334
335 ps_buf->ref_surface[0]->is_ref_surface = ps_buf->ref_surface[2]->is_ref_surface = 1;
336 ps_buf->ref_surface[1]->is_ref_surface = ps_buf->ref_surface[3]->is_ref_surface = 1;
337 #else
338 ps_buf->ref_surface = SURFACE(psPicParams->reference_picture);
339 ps_buf->rec_surface = SURFACE(psPicParams->reconstructed_picture);
340 #endif
341 ps_buf->coded_buf = BUFFER(psPicParams->coded_buf);
342
343 if (NULL == ps_buf->coded_buf) {
344 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s L%d Invalid coded buffer handle\n", __FUNCTION__, __LINE__);
345 free(psPicParams);
346 return VA_STATUS_ERROR_INVALID_BUFFER;
347 }
348
349 free(psPicParams);
350 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: end\n",__FUNCTION__);
351
352 return vaStatus;
353 }
354
tng__MPEG4ES_process_slice_param(context_ENC_p ctx,object_buffer_p obj_buffer)355 static VAStatus tng__MPEG4ES_process_slice_param(context_ENC_p ctx, object_buffer_p obj_buffer)
356 {
357 VAStatus vaStatus = VA_STATUS_SUCCESS;
358 VAEncSliceParameterBuffer *psSliceParams;
359
360 ASSERT(obj_buffer->type == VAEncSliceParameterBufferType);
361 /* Prepare InParams for macros of current slice, insert slice header, insert do slice command */
362
363 /* Transfer ownership of VAEncPictureParameterBufferMPEG4 data */
364 psSliceParams = (VAEncSliceParameterBuffer*) obj_buffer->buffer_data;
365 obj_buffer->size = 0;
366
367 //deblocking behaviour
368 ctx->bArbitrarySO = IMG_FALSE;
369 ctx->ui8DeblockIDC = psSliceParams->slice_flags.bits.disable_deblocking_filter_idc;
370 ++ctx->ui8SlicesPerPicture;
371 return vaStatus;
372 }
373
tng__MPEG4ES_process_misc_param(context_ENC_p ctx,object_buffer_p obj_buffer)374 static VAStatus tng__MPEG4ES_process_misc_param(context_ENC_p ctx, object_buffer_p obj_buffer)
375 {
376 VAStatus vaStatus = VA_STATUS_SUCCESS;
377 VAEncMiscParameterBuffer *pBuffer;
378 VAEncMiscParameterFrameRate *frame_rate_param;
379 VAEncMiscParameterRateControl *rate_control_param;
380 IMG_RC_PARAMS *psRCParams = &(ctx->sRCParams);
381
382 ASSERT(obj_buffer->type == VAEncMiscParameterBufferType);
383
384 /* Transfer ownership of VAEncMiscParameterBuffer data */
385 pBuffer = (VAEncMiscParameterBuffer *) obj_buffer->buffer_data;
386 obj_buffer->size = 0;
387
388 switch (pBuffer->type) {
389 case VAEncMiscParameterTypeRateControl:
390 rate_control_param = (VAEncMiscParameterRateControl *)pBuffer->data;
391
392 if (rate_control_param->initial_qp > 51 || rate_control_param->min_qp > 51) {
393 drv_debug_msg(VIDEO_DEBUG_ERROR, "Initial_qp(%d) and min_qpinitial_qp(%d) "
394 "are invalid.\nQP shouldn't be larger than 51 for MPEG4\n",
395 rate_control_param->initial_qp, rate_control_param->min_qp);
396 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
397 break;
398 }
399
400 drv_debug_msg(VIDEO_DEBUG_GENERAL, "rate control changed from %d to %d\n",
401 psRCParams->ui32BitsPerSecond,
402 rate_control_param->bits_per_second);
403
404 if ((rate_control_param->bits_per_second == psRCParams->ui32BitsPerSecond) &&
405 (psRCParams->ui32BufferSize == psRCParams->ui32BitsPerSecond / 1000 * rate_control_param->window_size) &&
406 (psRCParams->iMinQP == rate_control_param->min_qp) &&
407 (psRCParams->ui32InitialQp == rate_control_param->initial_qp))
408 break;
409
410 if (rate_control_param->bits_per_second > TOPAZ_MPEG4_MAX_BITRATE) {
411 psRCParams->ui32BitsPerSecond = TOPAZ_MPEG4_MAX_BITRATE;
412 drv_debug_msg(VIDEO_DEBUG_GENERAL, " bits_per_second(%d) exceeds \
413 the maximum bitrate, set it with %d\n",
414 rate_control_param->bits_per_second,
415 TOPAZ_MPEG4_MAX_BITRATE);
416 } else
417 psRCParams->ui32BitsPerSecond = rate_control_param->bits_per_second;
418
419 if (rate_control_param->window_size != 0)
420 psRCParams->ui32BufferSize = psRCParams->ui32BitsPerSecond * rate_control_param->window_size / 1000;
421 if (rate_control_param->initial_qp != 0)
422 psRCParams->ui32InitialQp = rate_control_param->initial_qp;
423 if (rate_control_param->min_qp != 0)
424 psRCParams->iMinQP = rate_control_param->min_qp;
425 break;
426 default:
427 break;
428 }
429
430 return vaStatus;
431 }
432
tng_MPEG4ES_RenderPicture(object_context_p obj_context,object_buffer_p * buffers,int num_buffers)433 static VAStatus tng_MPEG4ES_RenderPicture(
434 object_context_p obj_context,
435 object_buffer_p *buffers,
436 int num_buffers)
437 {
438 INIT_CONTEXT_MPEG4ES;
439 VAStatus vaStatus = VA_STATUS_SUCCESS;
440 int i;
441
442 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: start\n", __FUNCTION__);
443 for (i = 0; i < num_buffers; i++) {
444 object_buffer_p obj_buffer = buffers[i];
445 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: type = %d, num = %d\n", __FUNCTION__, obj_buffer->type, num_buffers);
446
447 switch (obj_buffer->type) {
448 case VAEncSequenceParameterBufferType:
449 drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_MPEG4_RenderPicture got VAEncSequenceParameterBufferType\n");
450 vaStatus = tng__MPEG4ES_process_sequence_param(ctx, obj_buffer);
451 DEBUG_FAILURE;
452 break;
453 case VAEncPictureParameterBufferType:
454 drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_MPEG4_RenderPicture got VAEncPictureParameterBuffer\n");
455 vaStatus = tng__MPEG4ES_process_picture_param(ctx, obj_buffer);
456 DEBUG_FAILURE;
457 break;
458
459 case VAEncSliceParameterBufferType:
460 drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_MPEG4_RenderPicture got VAEncSliceParameterBufferType\n");
461 vaStatus = tng__MPEG4ES_process_slice_param(ctx, obj_buffer);
462 DEBUG_FAILURE;
463 break;
464
465 case VAEncMiscParameterBufferType:
466 drv_debug_msg(VIDEO_DEBUG_GENERAL, "tng_MPEG4_RenderPicture got VAEncMiscParameterBufferType\n");
467 vaStatus = tng__MPEG4ES_process_misc_param(ctx, obj_buffer);
468 DEBUG_FAILURE;
469 break;
470 default:
471 vaStatus = VA_STATUS_ERROR_UNKNOWN;
472 DEBUG_FAILURE;
473 }
474 if (vaStatus != VA_STATUS_SUCCESS) {
475 break;
476 }
477 }
478 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: end\n", __FUNCTION__);
479
480 return vaStatus;
481 }
482
tng_MPEG4ES_EndPicture(object_context_p obj_context)483 static VAStatus tng_MPEG4ES_EndPicture(
484 object_context_p obj_context)
485 {
486 INIT_CONTEXT_MPEG4ES;
487 VAStatus vaStatus = VA_STATUS_SUCCESS;
488 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s start\n", __FUNCTION__);
489 vaStatus = tng_EndPicture(ctx);
490 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s end\n", __FUNCTION__);
491
492 return vaStatus;
493 }
494
495 struct format_vtable_s tng_MPEG4ES_vtable = {
496 queryConfigAttributes:
497 tng_MPEG4ES_QueryConfigAttributes,
498 validateConfig:
499 tng_MPEG4ES_ValidateConfig,
500 createContext:
501 tng_MPEG4ES_CreateContext,
502 destroyContext:
503 tng_MPEG4ES_DestroyContext,
504 beginPicture:
505 tng_MPEG4ES_BeginPicture,
506 renderPicture:
507 tng_MPEG4ES_RenderPicture,
508 endPicture:
509 tng_MPEG4ES_EndPicture
510 };
511
512 /*EOF*/
513