Home | History | Annotate | Download | only in src
      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 (at) intel.com>
     27  *    Zeng Li <zeng.li (at) intel.com>
     28  *    Edward Lin <edward.lin (at) intel.com>
     29  *    Zhaohan Ren <zhaohan.ren (at) 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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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