Home | History | Annotate | Download | only in src
      1 /*
      2  INTEL CONFIDENTIAL
      3  Copyright 2009 Intel Corporation All Rights Reserved.
      4  The source code contained or described herein and all documents related to the source code ("Material") are owned by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or its suppliers and licensors. The Material contains trade secrets and proprietary and confidential information of Intel or its suppliers and licensors. The Material is protected by worldwide copyright and trade secret laws and treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed, or disclosed in any way without Intels prior express written permission.
      5 
      6  No license under any patent, copyright, trade secret or other intellectual property right is granted to or conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement, estoppel or otherwise. Any license under such intellectual property rights must be express and approved by Intel in writing.
      7  */
      8 #include <glib.h>
      9 #include <string.h>
     10 #include <stdlib.h>
     11 
     12 #include "mixvideolog.h"
     13 
     14 #include "mixvideoformatenc_h264.h"
     15 #include "mixvideoconfigparamsenc_h264.h"
     16 
     17 #define MDEBUG
     18 #undef SHOW_SRC
     19 
     20 #ifdef SHOW_SRC
     21 Window win = 0;
     22 #endif /* SHOW_SRC */
     23 
     24 
     25 /* The parent class. The pointer will be saved
     26  * in this class's initialization. The pointer
     27  * can be used for chaining method call if needed.
     28  */
     29 static MixVideoFormatEncClass *parent_class = NULL;
     30 
     31 static void mix_videoformatenc_h264_finalize(GObject * obj);
     32 
     33 /*
     34  * Please note that the type we pass to G_DEFINE_TYPE is MIX_TYPE_VIDEOFORMATENC
     35  */
     36 G_DEFINE_TYPE (MixVideoFormatEnc_H264, mix_videoformatenc_h264, MIX_TYPE_VIDEOFORMATENC);
     37 
     38 static void mix_videoformatenc_h264_init(MixVideoFormatEnc_H264 * self) {
     39     MixVideoFormatEnc *parent = MIX_VIDEOFORMATENC(self);
     40 
     41     /* TODO: public member initialization */
     42 
     43     /* TODO: private member initialization */
     44     self->encoded_frames = 0;
     45     self->pic_skipped = FALSE;
     46     self->is_intra = TRUE;
     47     self->cur_fame = NULL;
     48     self->ref_fame = NULL;
     49     self->rec_fame = NULL;
     50 
     51     self->ci_shared_surfaces = NULL;
     52     self->surfaces= NULL;
     53     self->surface_num = 0;
     54 
     55     parent->initialized = FALSE;
     56 }
     57 
     58 static void mix_videoformatenc_h264_class_init(
     59         MixVideoFormatEnc_H264Class * klass) {
     60 
     61     /* root class */
     62     GObjectClass *gobject_class = (GObjectClass *) klass;
     63 
     64     /* direct parent class */
     65     MixVideoFormatEncClass *video_formatenc_class =
     66         MIX_VIDEOFORMATENC_CLASS(klass);
     67 
     68     /* parent class for later use */
     69     parent_class = g_type_class_peek_parent(klass);
     70 
     71     /* setup finializer */
     72     gobject_class->finalize = mix_videoformatenc_h264_finalize;
     73 
     74     /* setup vmethods with base implementation */
     75     /* TODO: decide if we need to override the parent's methods */
     76     video_formatenc_class->getcaps = mix_videofmtenc_h264_getcaps;
     77     video_formatenc_class->initialize = mix_videofmtenc_h264_initialize;
     78     video_formatenc_class->encode = mix_videofmtenc_h264_encode;
     79     video_formatenc_class->flush = mix_videofmtenc_h264_flush;
     80     video_formatenc_class->eos = mix_videofmtenc_h264_eos;
     81     video_formatenc_class->deinitialize = mix_videofmtenc_h264_deinitialize;
     82     video_formatenc_class->getmaxencodedbufsize = mix_videofmtenc_h264_get_max_encoded_buf_size;
     83 }
     84 
     85 MixVideoFormatEnc_H264 *
     86 mix_videoformatenc_h264_new(void) {
     87     MixVideoFormatEnc_H264 *ret =
     88         g_object_new(MIX_TYPE_VIDEOFORMATENC_H264, NULL);
     89 
     90     return ret;
     91 }
     92 
     93 void mix_videoformatenc_h264_finalize(GObject * obj) {
     94     /* clean up here. */
     95 
     96     /*MixVideoFormatEnc_H264 *mix = MIX_VIDEOFORMATENC_H264(obj); */
     97     GObjectClass *root_class = (GObjectClass *) parent_class;
     98 
     99     LOG_V( "\n");
    100 
    101     /* Chain up parent */
    102     if (root_class->finalize) {
    103         root_class->finalize(obj);
    104     }
    105 }
    106 
    107 MixVideoFormatEnc_H264 *
    108 mix_videoformatenc_h264_ref(MixVideoFormatEnc_H264 * mix) {
    109     return (MixVideoFormatEnc_H264 *) g_object_ref(G_OBJECT(mix));
    110 }
    111 
    112 /*H.264 vmethods implementation */
    113 MIX_RESULT mix_videofmtenc_h264_getcaps(MixVideoFormatEnc *mix, GString *msg) {
    114 
    115     /* TODO: add codes for H.264 */
    116 
    117     /* TODO: decide if we need to chainup parent method.
    118      * if we do, the following is the code:
    119      */
    120 
    121     LOG_V( "mix_videofmtenc_h264_getcaps\n");
    122 
    123     if (mix == NULL) {
    124         LOG_E( "mix == NULL\n");
    125         return MIX_RESULT_NULL_PTR;
    126     }
    127 
    128 
    129     if (parent_class->getcaps) {
    130         return parent_class->getcaps(mix, msg);
    131     }
    132     return MIX_RESULT_SUCCESS;
    133 }
    134 
    135 MIX_RESULT mix_videofmtenc_h264_initialize(MixVideoFormatEnc *mix,
    136         MixVideoConfigParamsEnc * config_params_enc,
    137         MixFrameManager * frame_mgr,
    138         MixBufferPool * input_buf_pool,
    139         MixSurfacePool ** surface_pool,
    140         VADisplay va_display ) {
    141 
    142     MIX_RESULT ret = MIX_RESULT_SUCCESS;
    143     MixVideoFormatEnc *parent = NULL;
    144     MixVideoConfigParamsEncH264 * config_params_enc_h264;
    145 
    146     VAStatus va_status = VA_STATUS_SUCCESS;
    147     VASurfaceID * surfaces;
    148 
    149     gint va_max_num_profiles, va_max_num_entrypoints, va_max_num_attribs;
    150     gint va_num_profiles,  va_num_entrypoints;
    151 
    152     VAProfile *va_profiles = NULL;
    153     VAEntrypoint *va_entrypoints = NULL;
    154     VAConfigAttrib va_attrib[2];
    155     guint index;
    156 
    157 
    158     /*frame_mgr and input_buf_pool is reservered for future use*/
    159 
    160     if (mix == NULL || config_params_enc == NULL || va_display == NULL) {
    161         LOG_E(
    162                 "mix == NULL || config_params_enc == NULL || va_display == NULL\n");
    163         return MIX_RESULT_NULL_PTR;
    164     }
    165 
    166     LOG_V( "begin\n");
    167 
    168 
    169     //TODO additional parameter checking
    170 
    171     /* Chainup parent method. */
    172 #if 1
    173     if (parent_class->initialize) {
    174         ret = parent_class->initialize(mix, config_params_enc,
    175                 frame_mgr, input_buf_pool, surface_pool,
    176                 va_display);
    177     }
    178 
    179     if (ret != MIX_RESULT_SUCCESS)
    180     {
    181         return ret;
    182     }
    183 
    184 #endif //disable it currently
    185 
    186     if (MIX_IS_VIDEOFORMATENC_H264(mix))
    187     {
    188         parent = MIX_VIDEOFORMATENC(&(mix->parent));
    189         MixVideoFormatEnc_H264 *self = MIX_VIDEOFORMATENC_H264(mix);
    190 
    191         if (MIX_IS_VIDEOCONFIGPARAMSENC_H264 (config_params_enc)) {
    192             config_params_enc_h264 =
    193                 MIX_VIDEOCONFIGPARAMSENC_H264 (config_params_enc);
    194         } else {
    195             LOG_V(
    196                     "mix_videofmtenc_h264_initialize:  no h264 config params found\n");
    197             return MIX_RESULT_FAIL;
    198         }
    199 
    200         g_mutex_lock(parent->objectlock);
    201 
    202         LOG_V(
    203                 "Start to get properities from h.264 params\n");
    204 
    205         /* get properties from H264 params Object, which is special to H264 format*/
    206         ret = mix_videoconfigparamsenc_h264_get_bus (config_params_enc_h264,
    207                 &self->basic_unit_size);
    208 
    209         if (ret != MIX_RESULT_SUCCESS) {
    210             //TODO cleanup
    211             LOG_E(
    212                     "Failed to mix_videoconfigparamsenc_h264_get_bus\n");
    213             g_mutex_unlock(parent->objectlock);
    214             return MIX_RESULT_FAIL;
    215         }
    216 
    217 
    218         ret = mix_videoconfigparamsenc_h264_get_dlk (config_params_enc_h264,
    219                 &self->disable_deblocking_filter_idc);
    220 
    221         if (ret != MIX_RESULT_SUCCESS) {
    222             //TODO cleanup
    223             LOG_E(
    224                     "Failed to mix_videoconfigparamsenc_h264_get_dlk\n");
    225             g_mutex_unlock(parent->objectlock);
    226             return MIX_RESULT_FAIL;
    227         }
    228 
    229 
    230         ret = mix_videoconfigparamsenc_h264_get_slice_num (config_params_enc_h264,
    231                 &self->slice_num);
    232 
    233         if (ret != MIX_RESULT_SUCCESS) {
    234             //TODO cleanup
    235             LOG_E(
    236                     "Failed to mix_videoconfigparamsenc_h264_get_slice_num\n");
    237             g_mutex_unlock(parent->objectlock);
    238             return MIX_RESULT_FAIL;
    239         }
    240 
    241         ret = mix_videoconfigparamsenc_h264_get_delimiter_type (config_params_enc_h264,
    242                 &self->delimiter_type);
    243 
    244         if (ret != MIX_RESULT_SUCCESS) {
    245             //TODO cleanup
    246             LOG_E (
    247                     "Failed to mix_videoconfigparamsenc_h264_get_delimiter_type\n");
    248             g_mutex_unlock(parent->objectlock);
    249             return MIX_RESULT_FAIL;
    250         }
    251 
    252         LOG_V(
    253                 "======H264 Encode Object properities======:\n");
    254 
    255         LOG_I( "self->basic_unit_size = %d\n",
    256                 self->basic_unit_size);
    257         LOG_I( "self->disable_deblocking_filter_idc = %d\n",
    258                 self->disable_deblocking_filter_idc);
    259         LOG_I( "self->slice_num = %d\n",
    260                 self->slice_num);
    261         LOG_I ("self->delimiter_type = %d\n",
    262                 self->delimiter_type);
    263 
    264         LOG_V(
    265                 "Get properities from params done\n");
    266 
    267 
    268     	//display = XOpenDisplay(NULL);
    269      	//va_display = vaGetDisplay (videoencobj->display);
    270 
    271         parent->va_display = va_display;
    272 
    273         LOG_V( "Get Display\n");
    274         LOG_I( "Display = 0x%08x\n",
    275                 (guint)va_display);
    276 
    277         //va_status = vaInitialize(va_display, &va_major_ver, &va_minor_ver);
    278         //g_print ("vaInitialize va_status = %d\n", va_status);
    279 
    280 
    281 #if 0
    282         /* query the vender information, can ignore*/
    283         va_vendor = vaQueryVendorString (va_display);
    284         LOG_I( "Vendor = %s\n",
    285                 va_vendor);
    286 #endif
    287 
    288         /*get the max number for profiles/entrypoints/attribs*/
    289         va_max_num_profiles = vaMaxNumProfiles(va_display);
    290         LOG_I( "va_max_num_profiles = %d\n",
    291                 va_max_num_profiles);
    292 
    293         va_max_num_entrypoints = vaMaxNumEntrypoints(va_display);
    294         LOG_I( "va_max_num_entrypoints = %d\n",
    295                 va_max_num_entrypoints);
    296 
    297         va_max_num_attribs = vaMaxNumConfigAttributes(va_display);
    298         LOG_I( "va_max_num_attribs = %d\n",
    299                 va_max_num_attribs);
    300 
    301         va_profiles = g_malloc(sizeof(VAProfile)*va_max_num_profiles);
    302         va_entrypoints = g_malloc(sizeof(VAEntrypoint)*va_max_num_entrypoints);
    303 
    304         if (va_profiles == NULL || va_entrypoints ==NULL)
    305         {
    306             LOG_E(
    307                     "!va_profiles || !va_entrypoints\n");
    308             g_mutex_unlock(parent->objectlock);
    309             return MIX_RESULT_NO_MEMORY;
    310         }
    311 
    312         LOG_I(
    313                 "va_profiles = 0x%08x\n", (guint)va_profiles);
    314 
    315         LOG_V( "vaQueryConfigProfiles\n");
    316 
    317 
    318         va_status = vaQueryConfigProfiles (va_display, va_profiles, &va_num_profiles);
    319 
    320         if (va_status != VA_STATUS_SUCCESS)
    321         {
    322             LOG_E(
    323                     "Failed to call vaQueryConfigProfiles\n");
    324             g_free(va_profiles);
    325             g_free (va_entrypoints);
    326             g_mutex_unlock(parent->objectlock);
    327             return MIX_RESULT_FAIL;
    328         }
    329 
    330         LOG_V( "vaQueryConfigProfiles Done\n");
    331 
    332 
    333 
    334         /*check whether profile is supported*/
    335         for(index= 0; index < va_num_profiles; index++) {
    336             if(parent->va_profile == va_profiles[index])
    337                 break;
    338         }
    339 
    340         if(index == va_num_profiles)
    341         {
    342             LOG_E( "Profile not supported\n");
    343             g_free(va_profiles);
    344             g_free (va_entrypoints);
    345             g_mutex_unlock(parent->objectlock);
    346             return MIX_RESULT_FAIL;  //Todo, add error handling here
    347         }
    348 
    349         LOG_V( "vaQueryConfigEntrypoints\n");
    350 
    351 
    352         /*Check entry point*/
    353         va_status = vaQueryConfigEntrypoints(va_display,
    354                 parent->va_profile,
    355                 va_entrypoints, &va_num_entrypoints);
    356 
    357         if (va_status != VA_STATUS_SUCCESS)
    358         {
    359             LOG_E(
    360                     "Failed to call vaQueryConfigEntrypoints\n");
    361             g_free(va_profiles);
    362             g_free (va_entrypoints);
    363             g_mutex_unlock(parent->objectlock);
    364             return MIX_RESULT_FAIL;
    365         }
    366 
    367         for (index = 0; index < va_num_entrypoints; index ++) {
    368             if (va_entrypoints[index] == VAEntrypointEncSlice) {
    369                 break;
    370             }
    371         }
    372 
    373         if (index == va_num_entrypoints) {
    374             LOG_E( "Entrypoint not found\n");
    375             g_free(va_profiles);
    376             g_free (va_entrypoints);
    377             g_mutex_unlock(parent->objectlock);
    378             return MIX_RESULT_FAIL;  //Todo, add error handling here
    379         }
    380 
    381 
    382         /*free profiles and entrypoints*/
    383         g_free(va_profiles);
    384         g_free (va_entrypoints);
    385 
    386         va_attrib[0].type = VAConfigAttribRTFormat;
    387         va_attrib[1].type = VAConfigAttribRateControl;
    388 
    389         LOG_V( "vaGetConfigAttributes\n");
    390 
    391         va_status = vaGetConfigAttributes(va_display, parent->va_profile,
    392                 parent->va_entrypoint,
    393                 &va_attrib[0], 2);
    394 
    395         if (va_status != VA_STATUS_SUCCESS)
    396         {
    397             LOG_E(
    398                     "Failed to call vaGetConfigAttributes\n");
    399             g_mutex_unlock(parent->objectlock);
    400             return MIX_RESULT_FAIL;
    401         }
    402 
    403         if ((va_attrib[0].value & parent->va_format) == 0) {
    404             LOG_E( "Matched format not found\n");
    405             g_mutex_unlock(parent->objectlock);
    406             return MIX_RESULT_FAIL;  //Todo, add error handling here
    407         }
    408 
    409 
    410         if ((va_attrib[1].value & parent->va_rcmode) == 0) {
    411             LOG_E( "RC mode not found\n");
    412             g_mutex_unlock(parent->objectlock);
    413             return MIX_RESULT_FAIL;  //Todo, add error handling here
    414         }
    415 
    416         va_attrib[0].value = parent->va_format; //VA_RT_FORMAT_YUV420;
    417         va_attrib[1].value = parent->va_rcmode;
    418 
    419         LOG_V( "======VA Configuration======\n");
    420 
    421         LOG_I( "profile = %d\n",
    422                 parent->va_profile);
    423         LOG_I( "va_entrypoint = %d\n",
    424                 parent->va_entrypoint);
    425         LOG_I( "va_attrib[0].type = %d\n",
    426                 va_attrib[0].type);
    427         LOG_I( "va_attrib[1].type = %d\n",
    428                 va_attrib[1].type);
    429         LOG_I( "va_attrib[0].value (Format) = %d\n",
    430                 va_attrib[0].value);
    431         LOG_I( "va_attrib[1].value (RC mode) = %d\n",
    432                 va_attrib[1].value);
    433 
    434         LOG_V( "vaCreateConfig\n");
    435 
    436         va_status = vaCreateConfig(va_display, parent->va_profile,
    437                 parent->va_entrypoint,
    438                 &va_attrib[0], 2, &(parent->va_config));
    439 
    440         if (va_status != VA_STATUS_SUCCESS)
    441         {
    442             LOG_E( "Failed vaCreateConfig\n");
    443             g_mutex_unlock(parent->objectlock);
    444             return MIX_RESULT_FAIL;
    445         }
    446 
    447         /*TODO: compute the surface number*/
    448         int numSurfaces;
    449 
    450         if (parent->share_buf_mode) {
    451             numSurfaces = 2;
    452         }
    453         else {
    454             numSurfaces = 8;
    455             parent->ci_frame_num = 0;
    456         }
    457 
    458         self->surface_num = numSurfaces + parent->ci_frame_num;
    459 
    460         surfaces = g_malloc(sizeof(VASurfaceID)*numSurfaces);
    461 
    462         if (surfaces == NULL)
    463         {
    464             LOG_E(
    465                     "Failed allocate surface\n");
    466             g_mutex_unlock(parent->objectlock);
    467             return MIX_RESULT_NO_MEMORY;
    468         }
    469 
    470         LOG_V( "vaCreateSurfaces\n");
    471 
    472         va_status = vaCreateSurfaces(va_display, parent->picture_width,
    473                 parent->picture_height, parent->va_format,
    474                 numSurfaces, surfaces);
    475         //TODO check vret and return fail if needed
    476 
    477         if (va_status != VA_STATUS_SUCCESS)
    478         {
    479             LOG_E(
    480                     "Failed vaCreateSurfaces\n");
    481             g_mutex_unlock(parent->objectlock);
    482             return MIX_RESULT_FAIL;
    483         }
    484 
    485         if (parent->share_buf_mode) {
    486 
    487             LOG_V(
    488                     "We are in share buffer mode!\n");
    489             self->ci_shared_surfaces =
    490                 g_malloc(sizeof(VASurfaceID) * parent->ci_frame_num);
    491 
    492             if (self->ci_shared_surfaces == NULL)
    493             {
    494                 LOG_E(
    495                         "Failed allocate shared surface\n");
    496                 g_mutex_unlock(parent->objectlock);
    497                 return MIX_RESULT_NO_MEMORY;
    498             }
    499 
    500             guint index;
    501             for(index = 0; index < parent->ci_frame_num; index++) {
    502 
    503                 LOG_I( "ci_frame_id = %lu\n",
    504                         parent->ci_frame_id[index]);
    505 
    506                 LOG_V(
    507                         "vaCreateSurfaceFromCIFrame\n");
    508 
    509                 va_status = vaCreateSurfaceFromCIFrame(va_display,
    510                         (gulong) (parent->ci_frame_id[index]),
    511                         &self->ci_shared_surfaces[index]);
    512                 if (va_status != VA_STATUS_SUCCESS)
    513                 {
    514                     LOG_E(
    515                             "Failed to vaCreateSurfaceFromCIFrame\n");
    516                     g_mutex_unlock(parent->objectlock);
    517                     return MIX_RESULT_FAIL;
    518                 }
    519             }
    520 
    521             LOG_V(
    522                     "vaCreateSurfaceFromCIFrame Done\n");
    523 
    524         }// if (parent->share_buf_mode)
    525 
    526         self->surfaces = g_malloc(sizeof(VASurfaceID) * self->surface_num);
    527 
    528         if (self->surfaces == NULL)
    529         {
    530             LOG_E(
    531                     "Failed allocate private surface\n");
    532             g_free (surfaces);
    533             g_mutex_unlock(parent->objectlock);
    534             return MIX_RESULT_NO_MEMORY;
    535         }
    536 
    537         if (parent->share_buf_mode) {
    538             /*shared surfaces should be put in pool first,
    539              * because we will get it accoring to CI index*/
    540             for(index = 0; index < parent->ci_frame_num; index++)
    541                 self->surfaces[index] = self->ci_shared_surfaces[index];
    542         }
    543 
    544         for(index = 0; index < numSurfaces; index++) {
    545             self->surfaces[index + parent->ci_frame_num] = surfaces[index];
    546         }
    547 
    548         LOG_V( "assign surface Done\n");
    549         LOG_I( "Created %d libva surfaces\n",
    550                 numSurfaces + parent->ci_frame_num);
    551 
    552 #if 0  //current put this in gst
    553         images = g_malloc(sizeof(VAImage)*numSurfaces);
    554         if (images == NULL)
    555         {
    556             g_mutex_unlock(parent->objectlock);
    557             return MIX_RESULT_FAIL;
    558         }
    559 
    560         for (index = 0; index < numSurfaces; index++) {
    561             //Derive an VAImage from an existing surface.
    562             //The image buffer can then be mapped/unmapped for CPU access
    563             va_status = vaDeriveImage(va_display, surfaces[index],
    564                     &images[index]);
    565         }
    566 #endif
    567 
    568         LOG_V( "mix_surfacepool_new\n");
    569 
    570         parent->surfacepool = mix_surfacepool_new();
    571         if (surface_pool)
    572             *surface_pool = parent->surfacepool;
    573         //which is useful to check before encode
    574 
    575         if (parent->surfacepool == NULL)
    576         {
    577             LOG_E(
    578                     "Failed to mix_surfacepool_new\n");
    579             g_free (surfaces);
    580             g_mutex_unlock(parent->objectlock);
    581             return MIX_RESULT_FAIL;
    582         }
    583 
    584         LOG_V(
    585                 "mix_surfacepool_initialize\n");
    586 
    587         ret = mix_surfacepool_initialize(parent->surfacepool,
    588                 self->surfaces, parent->ci_frame_num + numSurfaces);
    589 
    590         switch (ret)
    591         {
    592             case MIX_RESULT_SUCCESS:
    593                 break;
    594             case MIX_RESULT_ALREADY_INIT:
    595                 //TODO cleanup and/or retry
    596                 g_free (surfaces);
    597                 g_mutex_unlock(parent->objectlock);
    598                 return MIX_RESULT_FAIL;
    599             default:
    600                 break;
    601         }
    602 
    603 
    604         //Initialize and save the VA context ID
    605         LOG_V( "vaCreateContext\n");
    606 
    607         va_status = vaCreateContext(va_display, parent->va_config,
    608                 parent->picture_width, parent->picture_height,
    609                 0, self->surfaces, parent->ci_frame_num + numSurfaces,
    610                 &(parent->va_context));
    611 
    612         LOG_I(
    613                 "Created libva context width %d, height %d\n",
    614                 parent->picture_width, parent->picture_height);
    615 
    616         if (va_status != VA_STATUS_SUCCESS)
    617         {
    618             LOG_E(
    619                     "Failed to vaCreateContext\n");
    620             LOG_I( "va_status = %d\n",
    621                     (guint)va_status);
    622             g_free (surfaces);
    623             g_mutex_unlock(parent->objectlock);
    624             return MIX_RESULT_FAIL;
    625         }
    626 
    627         guint max_size = 0;
    628         ret = mix_videofmtenc_h264_get_max_encoded_buf_size (parent, &max_size);
    629         if (ret != MIX_RESULT_SUCCESS)
    630         {
    631             LOG_E(
    632                     "Failed to mix_videofmtenc_h264_get_max_encoded_buf_size\n");
    633             g_free (surfaces);
    634             g_mutex_unlock(parent->objectlock);
    635             return MIX_RESULT_FAIL;
    636 
    637         }
    638 
    639         /*Create coded buffer for output*/
    640         va_status = vaCreateBuffer (va_display, parent->va_context,
    641                 VAEncCodedBufferType,
    642                 self->coded_buf_size,  //
    643                 1, NULL,
    644                 &self->coded_buf);
    645 
    646         if (va_status != VA_STATUS_SUCCESS)
    647         {
    648             LOG_E(
    649                     "Failed to vaCreateBuffer: VAEncCodedBufferType\n");
    650             g_free (surfaces);
    651             g_mutex_unlock(parent->objectlock);
    652             return MIX_RESULT_FAIL;
    653         }
    654 
    655 #ifdef SHOW_SRC
    656         Display * display = XOpenDisplay (NULL);
    657 
    658         LOG_I( "display = 0x%08x\n",
    659                 (guint) display);
    660         win = XCreateSimpleWindow(display, RootWindow(display, 0), 0, 0,
    661                 parent->picture_width,  parent->picture_height, 0, 0,
    662                 WhitePixel(display, 0));
    663         XMapWindow(display, win);
    664         XSelectInput(display, win, KeyPressMask | StructureNotifyMask);
    665 
    666         XSync(display, False);
    667         LOG_I( "va_display = 0x%08x\n",
    668                 (guint) va_display);
    669 
    670 #endif /* SHOW_SRC */
    671 
    672         parent->initialized = TRUE;
    673 
    674         g_mutex_unlock(parent->objectlock);
    675         g_free (surfaces);
    676 
    677     }
    678     else
    679     {
    680         LOG_E(
    681                 "not H264 video encode Object\n");
    682         return MIX_RESULT_FAIL;
    683 
    684     }
    685 
    686     LOG_V( "end\n");
    687 
    688     return MIX_RESULT_SUCCESS;
    689 }
    690 
    691 MIX_RESULT mix_videofmtenc_h264_encode(MixVideoFormatEnc *mix, MixBuffer * bufin[],
    692         gint bufincnt, MixIOVec * iovout[], gint iovoutcnt,
    693         MixVideoEncodeParams * encode_params) {
    694 
    695     MIX_RESULT ret = MIX_RESULT_SUCCESS;
    696     MixVideoFormatEnc *parent = NULL;
    697 
    698     LOG_V( "Begin\n");
    699 
    700     /*currenly only support one input and output buffer*/
    701     //TODO: params i
    702 
    703     if (bufincnt != 1 || iovoutcnt != 1) {
    704         LOG_E(
    705                 "buffer count not equel to 1\n");
    706         LOG_E(
    707                 "maybe some exception occurs\n");
    708     }
    709 
    710     if (mix == NULL ||bufin[0] == NULL ||  iovout[0] == NULL) {
    711         LOG_E(
    712                 "!mix || !bufin[0] ||!iovout[0]\n");
    713         return MIX_RESULT_NULL_PTR;
    714     }
    715 
    716     //TODO: encode_params is reserved here for future usage.
    717 
    718     /* TODO: decide if we need to chainup parent method.
    719      *      * * if we do, the following is the code:
    720      * */
    721 
    722 #if 0
    723     if (parent_class->encode) {
    724         return parent_class->encode(mix, bufin, bufincnt, iovout,
    725                 iovoutcnt, encode_params);
    726     }
    727 #endif
    728 
    729     if (MIX_IS_VIDEOFORMATENC_H264(mix))
    730     {
    731 
    732         parent = MIX_VIDEOFORMATENC(&(mix->parent));
    733         MixVideoFormatEnc_H264 *self = MIX_VIDEOFORMATENC_H264 (mix);
    734 
    735         LOG_V( "Locking\n");
    736         g_mutex_lock(parent->objectlock);
    737 
    738 
    739         //TODO: also we could move some encode Preparation work to here
    740 
    741         LOG_V(
    742                 "mix_videofmtenc_h264_process_encode\n");
    743 
    744         ret = mix_videofmtenc_h264_process_encode (self,
    745                 bufin[0], iovout[0]);
    746         if (ret != MIX_RESULT_SUCCESS)
    747         {
    748             LOG_E(
    749                     "Failed mix_videofmtenc_h264_process_encode\n");
    750             g_mutex_unlock(parent->objectlock);
    751             return MIX_RESULT_FAIL;
    752         }
    753 
    754 
    755         LOG_V( "UnLocking\n");
    756 
    757         g_mutex_unlock(parent->objectlock);
    758     }
    759     else
    760     {
    761         LOG_E(
    762                 "not H264 video encode Object\n");
    763         return MIX_RESULT_FAIL;
    764     }
    765 
    766     LOG_V( "end\n");
    767 
    768     return MIX_RESULT_SUCCESS;
    769 }
    770 
    771 MIX_RESULT mix_videofmtenc_h264_flush(MixVideoFormatEnc *mix) {
    772 
    773     //MIX_RESULT ret = MIX_RESULT_SUCCESS;
    774 
    775     LOG_V( "Begin\n");
    776 
    777     if (mix == NULL) {
    778         LOG_E( "mix == NULL\n");
    779         return MIX_RESULT_NULL_PTR;
    780     }
    781 
    782 
    783     /*not chain to parent flush func*/
    784 #if 0
    785     if (parent_class->flush) {
    786         return parent_class->flush(mix, msg);
    787     }
    788 #endif
    789 
    790     MixVideoFormatEnc_H264 *self = MIX_VIDEOFORMATENC_H264(mix);
    791 
    792     g_mutex_lock(mix->objectlock);
    793 
    794 #if 0
    795     /*unref the current source surface*/
    796     if (self->cur_fame != NULL)
    797     {
    798         mix_videoframe_unref (self->cur_fame);
    799         self->cur_fame = NULL;
    800     }
    801 #endif
    802 
    803     /*unref the reconstructed surface*/
    804     if (self->rec_fame != NULL)
    805     {
    806         mix_videoframe_unref (self->rec_fame);
    807         self->rec_fame = NULL;
    808     }
    809 
    810     /*unref the reference surface*/
    811     if (self->ref_fame != NULL)
    812     {
    813         mix_videoframe_unref (self->ref_fame);
    814         self->ref_fame = NULL;
    815     }
    816 
    817     /*reset the properities*/
    818     self->encoded_frames = 0;
    819     self->pic_skipped = FALSE;
    820     self->is_intra = TRUE;
    821 
    822     g_mutex_unlock(mix->objectlock);
    823 
    824     LOG_V( "end\n");
    825 
    826     return MIX_RESULT_SUCCESS;
    827 }
    828 
    829 MIX_RESULT mix_videofmtenc_h264_eos(MixVideoFormatEnc *mix) {
    830 
    831     /* TODO: add codes for H.264 */
    832 
    833     /* TODO: decide if we need to chainup parent method.
    834      * if we do, the following is the code:
    835      */
    836 
    837     LOG_V( "\n");
    838 
    839     if (mix == NULL) {
    840         LOG_E( "mix == NULL\n");
    841         return MIX_RESULT_NULL_PTR;
    842     }
    843 
    844     if (parent_class->eos) {
    845         return parent_class->eos(mix);
    846     }
    847     return MIX_RESULT_SUCCESS;
    848 }
    849 
    850 MIX_RESULT mix_videofmtenc_h264_deinitialize(MixVideoFormatEnc *mix) {
    851 
    852     MixVideoFormatEnc *parent = NULL;
    853     VAStatus va_status;
    854 
    855     LOG_V( "Begin\n");
    856 
    857     if (mix == NULL) {
    858         LOG_E( "mix == NULL\n");
    859         return MIX_RESULT_NULL_PTR;
    860     }
    861 
    862     parent = MIX_VIDEOFORMATENC(&(mix->parent));
    863     MixVideoFormatEnc_H264 *self = MIX_VIDEOFORMATENC_H264(mix);
    864 
    865     LOG_V( "Release frames\n");
    866 
    867     g_mutex_lock(parent->objectlock);
    868 
    869 #if 0
    870     /*unref the current source surface*/
    871     if (self->cur_fame != NULL)
    872     {
    873         mix_videoframe_unref (self->cur_fame);
    874         self->cur_fame = NULL;
    875     }
    876 #endif
    877 
    878     /*unref the reconstructed surface*/
    879     if (self->rec_fame != NULL)
    880     {
    881         mix_videoframe_unref (self->rec_fame);
    882         self->rec_fame = NULL;
    883     }
    884 
    885     /*unref the reference surface*/
    886     if (self->ref_fame != NULL)
    887     {
    888         mix_videoframe_unref (self->ref_fame);
    889         self->ref_fame = NULL;
    890     }
    891 
    892     LOG_V( "Release surfaces\n");
    893 
    894     if (self->ci_shared_surfaces)
    895     {
    896         g_free (self->ci_shared_surfaces);
    897         self->ci_shared_surfaces = NULL;
    898     }
    899 
    900     if (self->surfaces)
    901     {
    902         g_free (self->surfaces);
    903         self->surfaces = NULL;
    904     }
    905 
    906     LOG_V( "vaDestroyContext\n");
    907 
    908     va_status = vaDestroyContext (parent->va_display, parent->va_context);
    909     if (va_status != VA_STATUS_SUCCESS)
    910     {
    911         LOG_E(
    912                 "Failed vaDestroyContext\n");
    913         g_mutex_unlock(parent->objectlock);
    914         return MIX_RESULT_FAIL;
    915     }
    916 
    917     LOG_V( "vaDestroyConfig\n");
    918 
    919     va_status = vaDestroyConfig (parent->va_display, parent->va_config);
    920     if (va_status != VA_STATUS_SUCCESS)
    921     {
    922         LOG_E(
    923                 "Failed vaDestroyConfig\n");
    924         g_mutex_unlock(parent->objectlock);
    925         return MIX_RESULT_FAIL;
    926     }
    927 
    928     parent->initialized = TRUE;
    929 
    930     g_mutex_unlock(parent->objectlock);
    931 
    932 #if 1
    933     if (parent_class->deinitialize) {
    934         return parent_class->deinitialize(mix);
    935     }
    936 #endif
    937 
    938     //Most stuff is cleaned up in parent_class->finalize()
    939 
    940     LOG_V( "end\n");
    941 
    942     return MIX_RESULT_SUCCESS;
    943 }
    944 
    945 MIX_RESULT mix_videofmtenc_h264_send_seq_params (MixVideoFormatEnc_H264 *mix)
    946 {
    947 
    948     VAStatus va_status;
    949     VAEncSequenceParameterBufferH264 h264_seq_param;
    950 
    951     MixVideoFormatEnc *parent = NULL;
    952 
    953     if (mix == NULL)
    954         return MIX_RESULT_NULL_PTR;
    955 
    956     LOG_V( "Begin\n\n");
    957 
    958     if (MIX_IS_VIDEOFORMATENC_H264(mix))
    959     {
    960         parent = MIX_VIDEOFORMATENC(&(mix->parent));
    961 
    962         /*set up the sequence params for HW*/
    963         h264_seq_param.level_idc = 30;  //TODO, hard code now
    964         h264_seq_param.intra_period = parent->intra_period;
    965         h264_seq_param.picture_width_in_mbs = parent->picture_width / 16;
    966         h264_seq_param.picture_height_in_mbs = parent->picture_height/ 16;
    967         h264_seq_param.bits_per_second = parent->bitrate;
    968         h264_seq_param.frame_rate =
    969 			(unsigned int) (parent->frame_rate_num + parent->frame_rate_denom /2 ) / parent->frame_rate_denom;
    970         h264_seq_param.initial_qp = parent->initial_qp;
    971         h264_seq_param.min_qp = parent->min_qp;
    972         h264_seq_param.basic_unit_size = mix->basic_unit_size; //for rate control usage
    973         h264_seq_param.intra_period = parent->intra_period;
    974         //h264_seq_param.vui_flag = 248;
    975         //h264_seq_param.seq_parameter_set_id = 176;
    976 
    977         LOG_V(
    978                 "===h264 sequence params===\n");
    979 
    980         LOG_I( "seq_parameter_set_id = %d\n",
    981                 (guint)h264_seq_param.seq_parameter_set_id);
    982         LOG_I( "level_idc = %d\n",
    983                 (guint)h264_seq_param.level_idc);
    984         LOG_I( "intra_period = %d\n",
    985                 h264_seq_param.intra_period);
    986         LOG_I( "picture_width_in_mbs = %d\n",
    987                 h264_seq_param.picture_width_in_mbs);
    988         LOG_I( "picture_height_in_mbs = %d\n",
    989                 h264_seq_param.picture_height_in_mbs);
    990         LOG_I( "bitrate = %d\n",
    991                 h264_seq_param.bits_per_second);
    992         LOG_I( "frame_rate = %d\n",
    993                 h264_seq_param.frame_rate);
    994         LOG_I( "initial_qp = %d\n",
    995                 h264_seq_param.initial_qp);
    996         LOG_I( "min_qp = %d\n",
    997                 h264_seq_param.min_qp);
    998         LOG_I( "basic_unit_size = %d\n",
    999                 h264_seq_param.basic_unit_size);
   1000         LOG_I( "vui_flag = %d\n\n",
   1001                 h264_seq_param.vui_flag);
   1002 
   1003         va_status = vaCreateBuffer(parent->va_display, parent->va_context,
   1004                 VAEncSequenceParameterBufferType,
   1005                 sizeof(h264_seq_param),
   1006                 1, &h264_seq_param,
   1007                 &mix->seq_param_buf);
   1008         if (va_status != VA_STATUS_SUCCESS)
   1009         {
   1010             LOG_E(
   1011                     "Failed to vaCreateBuffer\n");
   1012             return MIX_RESULT_FAIL;
   1013         }
   1014 
   1015         va_status = vaRenderPicture(parent->va_display, parent->va_context,
   1016                 &mix->seq_param_buf, 1);
   1017         if (va_status != VA_STATUS_SUCCESS)
   1018         {
   1019             LOG_E(
   1020                     "Failed to vaRenderPicture\n");
   1021             return MIX_RESULT_FAIL;
   1022         }
   1023     }
   1024     else
   1025     {
   1026         LOG_E(
   1027                 "not H264 video encode Object\n");
   1028         return MIX_RESULT_FAIL;
   1029     }
   1030 
   1031     LOG_V( "end\n");
   1032 
   1033     return MIX_RESULT_SUCCESS;
   1034 
   1035 
   1036 }
   1037 
   1038 MIX_RESULT mix_videofmtenc_h264_send_picture_parameter (MixVideoFormatEnc_H264 *mix)
   1039 {
   1040     VAStatus va_status;
   1041     VAEncPictureParameterBufferH264 h264_pic_param;
   1042     MixVideoFormatEnc *parent = NULL;
   1043 
   1044     if (mix == NULL)
   1045         return MIX_RESULT_NULL_PTR;
   1046 
   1047     LOG_V( "Begin\n\n");
   1048 
   1049 #if 0 //not needed currently
   1050     MixVideoConfigParamsEncH264 * params_h264
   1051         = MIX_VIDEOCONFIGPARAMSENC_H264 (config_params_enc);
   1052 #endif
   1053 
   1054     if (MIX_IS_VIDEOFORMATENC_H264(mix)) {
   1055 
   1056         parent = MIX_VIDEOFORMATENC(&(mix->parent));
   1057 
   1058         /*set picture params for HW*/
   1059         h264_pic_param.reference_picture = mix->ref_fame->frame_id;
   1060         h264_pic_param.reconstructed_picture = mix->rec_fame->frame_id;
   1061         h264_pic_param.coded_buf = mix->coded_buf;
   1062         h264_pic_param.picture_width = parent->picture_width;
   1063         h264_pic_param.picture_height = parent->picture_height;
   1064         h264_pic_param.last_picture = 0;
   1065 
   1066 
   1067         LOG_V(
   1068                 "======h264 picture params======\n");
   1069         LOG_I( "reference_picture = 0x%08x\n",
   1070                 h264_pic_param.reference_picture);
   1071         LOG_I( "reconstructed_picture = 0x%08x\n",
   1072                 h264_pic_param.reconstructed_picture);
   1073         LOG_I( "coded_buf = 0x%08x\n",
   1074                 h264_pic_param.coded_buf);
   1075         LOG_I( "picture_width = %d\n",
   1076                 h264_pic_param.picture_width);
   1077         LOG_I( "picture_height = %d\n\n",
   1078                 h264_pic_param.picture_height);
   1079 
   1080         va_status = vaCreateBuffer(parent->va_display, parent->va_context,
   1081                 VAEncPictureParameterBufferType,
   1082                 sizeof(h264_pic_param),
   1083                 1,&h264_pic_param,
   1084                 &mix->pic_param_buf);
   1085 
   1086         if (va_status != VA_STATUS_SUCCESS)
   1087         {
   1088             LOG_E(
   1089                     "Failed to vaCreateBuffer\n");
   1090             return MIX_RESULT_FAIL;
   1091         }
   1092 
   1093 
   1094         va_status = vaRenderPicture(parent->va_display, parent->va_context,
   1095                 &mix->pic_param_buf, 1);
   1096 
   1097         if (va_status != VA_STATUS_SUCCESS)
   1098         {
   1099             LOG_E(
   1100                     "Failed to vaRenderPicture\n");
   1101             return MIX_RESULT_FAIL;
   1102         }
   1103     }
   1104     else
   1105     {
   1106         LOG_E(
   1107                 "not H264 video encode Object\n");
   1108         return MIX_RESULT_FAIL;
   1109     }
   1110 
   1111     LOG_V( "end\n");
   1112     return MIX_RESULT_SUCCESS;
   1113 
   1114 }
   1115 
   1116 
   1117 MIX_RESULT mix_videofmtenc_h264_send_slice_parameter (MixVideoFormatEnc_H264 *mix)
   1118 {
   1119     VAStatus va_status;
   1120 
   1121     guint slice_num;
   1122     guint slice_height;
   1123     guint slice_index;
   1124     guint slice_height_in_mb;
   1125 
   1126     if (mix == NULL)
   1127         return MIX_RESULT_NULL_PTR;
   1128 
   1129     LOG_V( "Begin\n\n");
   1130 
   1131 
   1132     MixVideoFormatEnc *parent = NULL;
   1133 
   1134     if (MIX_IS_VIDEOFORMATENC_H264(mix))
   1135     {
   1136         parent = MIX_VIDEOFORMATENC(&(mix->parent));
   1137 
   1138         slice_num = mix->slice_num;
   1139         slice_height = parent->picture_height / slice_num;
   1140 
   1141         slice_height += 15;
   1142         slice_height &= (~15);
   1143 
   1144 #if 1
   1145         va_status = vaCreateBuffer (parent->va_display, parent->va_context,
   1146                 VAEncSliceParameterBufferType,
   1147                 sizeof(VAEncSliceParameterBuffer),
   1148                 slice_num, NULL,
   1149                 &mix->slice_param_buf);
   1150 
   1151         if (va_status != VA_STATUS_SUCCESS)
   1152         {
   1153             LOG_E(
   1154                     "Failed to vaCreateBuffer\n");
   1155             return MIX_RESULT_FAIL;
   1156         }
   1157 
   1158         VAEncSliceParameterBuffer *slice_param, *current_slice;
   1159 
   1160         va_status = vaMapBuffer(parent->va_display,
   1161                 mix->slice_param_buf,
   1162                 (void **)&slice_param);
   1163 
   1164         if (va_status != VA_STATUS_SUCCESS)
   1165         {
   1166             LOG_E(
   1167                     "Failed to vaMapBuffer\n");
   1168             return MIX_RESULT_FAIL;
   1169         }
   1170 
   1171         current_slice = slice_param;
   1172 
   1173 
   1174         for (slice_index = 0; slice_index < slice_num; slice_index++) {
   1175             current_slice = slice_param + slice_index;
   1176             slice_height_in_mb =
   1177                 min (slice_height, parent->picture_height
   1178                         - slice_index * slice_height) / 16;
   1179 
   1180             // starting MB row number for this slice
   1181             current_slice->start_row_number = slice_index * slice_height / 16;
   1182             // slice height measured in MB
   1183             current_slice->slice_height = slice_height_in_mb;
   1184             current_slice->slice_flags.bits.is_intra = mix->is_intra;
   1185             current_slice->slice_flags.bits.disable_deblocking_filter_idc
   1186                 = mix->disable_deblocking_filter_idc;
   1187 
   1188             LOG_V(
   1189                     "======h264 slice params======\n");
   1190 
   1191             LOG_I( "slice_index = %d\n",
   1192                     (gint) slice_index);
   1193             LOG_I( "start_row_number = %d\n",
   1194                     (gint) current_slice->start_row_number);
   1195             LOG_I( "slice_height_in_mb = %d\n",
   1196                     (gint) current_slice->slice_height);
   1197             LOG_I( "slice.is_intra = %d\n",
   1198                     (gint) current_slice->slice_flags.bits.is_intra);
   1199             LOG_I(
   1200                     "disable_deblocking_filter_idc = %d\n\n",
   1201                     (gint) mix->disable_deblocking_filter_idc);
   1202 
   1203         }
   1204 
   1205         va_status = vaUnmapBuffer(parent->va_display, mix->slice_param_buf);
   1206 
   1207         if (va_status != VA_STATUS_SUCCESS)
   1208         {
   1209             LOG_E(
   1210                     "Failed to vaUnmapBuffer\n");
   1211             return MIX_RESULT_FAIL;
   1212         }
   1213 #endif
   1214 
   1215 #if 0
   1216             VAEncSliceParameterBuffer slice_param;
   1217             slice_index = 0;
   1218             slice_height_in_mb = slice_height / 16;
   1219             slice_param.start_row_number = 0;
   1220             slice_param.slice_height = slice_height / 16;
   1221             slice_param.slice_flags.bits.is_intra = mix->is_intra;
   1222             slice_param.slice_flags.bits.disable_deblocking_filter_idc
   1223                 = mix->disable_deblocking_filter_idc;
   1224 
   1225             va_status = vaCreateBuffer (parent->va_display, parent->va_context,
   1226                     VAEncSliceParameterBufferType,
   1227                     sizeof(slice_param),
   1228                     slice_num, &slice_param,
   1229                     &mix->slice_param_buf);
   1230 
   1231             if (va_status != VA_STATUS_SUCCESS)
   1232             {
   1233                 LOG_E(
   1234                         "Failed to vaCreateBuffer\n");
   1235                 return MIX_RESULT_FAIL;
   1236             }
   1237 #endif
   1238 
   1239         va_status = vaRenderPicture(parent->va_display, parent->va_context,
   1240                 &mix->slice_param_buf, 1);
   1241 
   1242         if (va_status != VA_STATUS_SUCCESS)
   1243         {
   1244             LOG_E(
   1245                     "Failed to vaRenderPicture\n");
   1246             return MIX_RESULT_FAIL;
   1247         }
   1248 
   1249     }
   1250     else
   1251     {
   1252         LOG_E(
   1253                 "not H264 video encode Object\n");
   1254         return MIX_RESULT_FAIL;
   1255     }
   1256 
   1257     LOG_V( "end\n");
   1258 
   1259     return MIX_RESULT_SUCCESS;
   1260 }
   1261 
   1262 MIX_RESULT mix_videofmtenc_h264_process_encode (MixVideoFormatEnc_H264 *mix,
   1263         MixBuffer * bufin, MixIOVec * iovout)
   1264 {
   1265 
   1266     MIX_RESULT ret = MIX_RESULT_SUCCESS;
   1267     VAStatus va_status = VA_STATUS_SUCCESS;
   1268     VADisplay va_display = NULL;
   1269     VAContextID va_context;
   1270     gulong surface = 0;
   1271     guint16 width, height;
   1272 
   1273     MixVideoFrame *  tmp_fame;
   1274     guint8 *buf;
   1275 
   1276     if ((mix == NULL) || (bufin == NULL) || (iovout == NULL)) {
   1277         LOG_E(
   1278                 "mix == NUL) || bufin == NULL || iovout == NULL\n");
   1279         return MIX_RESULT_NULL_PTR;
   1280     }
   1281 
   1282     LOG_V( "Begin\n");
   1283 
   1284     if (MIX_IS_VIDEOFORMATENC_H264(mix))
   1285     {
   1286 
   1287         MixVideoFormatEnc *parent = MIX_VIDEOFORMATENC(&(mix->parent));
   1288 
   1289         va_display = parent->va_display;
   1290         va_context = parent->va_context;
   1291         width = parent->picture_width;
   1292         height = parent->picture_height;
   1293 
   1294 
   1295         LOG_I( "encoded_frames = %d\n",
   1296                 mix->encoded_frames);
   1297         LOG_I( "is_intra = %d\n",
   1298                 mix->is_intra);
   1299         LOG_I( "ci_frame_id = 0x%08x\n",
   1300                 (guint) parent->ci_frame_id);
   1301 
   1302         /* determine the picture type*/
   1303         if ((mix->encoded_frames % parent->intra_period) == 0) {
   1304             mix->is_intra = TRUE;
   1305         } else {
   1306             mix->is_intra = FALSE;
   1307         }
   1308 
   1309         LOG_I( "is_intra_picture = %d\n",
   1310                 mix->is_intra);
   1311 
   1312         LOG_V(
   1313                 "Get Surface from the pool\n");
   1314 
   1315         /*current we use one surface for source data,
   1316          * one for reference and one for reconstructed*/
   1317         /*TODO, could be refine here*/
   1318 
   1319         if (!parent->share_buf_mode) {
   1320             LOG_V(
   1321                     "We are NOT in share buffer mode\n");
   1322 
   1323             if (mix->ref_fame == NULL)
   1324             {
   1325                 ret = mix_surfacepool_get(parent->surfacepool, &mix->ref_fame);
   1326                 if (ret != MIX_RESULT_SUCCESS)  //#ifdef SLEEP_SURFACE not used
   1327                 {
   1328                     LOG_E(
   1329                             "Failed to mix_surfacepool_get\n");
   1330                     return MIX_RESULT_FAIL;
   1331                 }
   1332             }
   1333 
   1334             if (mix->rec_fame == NULL)
   1335             {
   1336                 ret = mix_surfacepool_get(parent->surfacepool, &mix->rec_fame);
   1337                 if (ret != MIX_RESULT_SUCCESS)
   1338                 {
   1339                     LOG_E(
   1340                             "Failed to mix_surfacepool_get\n");
   1341                     return MIX_RESULT_FAIL;
   1342                 }
   1343             }
   1344 
   1345             if (parent->need_display) {
   1346                 mix->cur_fame = NULL;
   1347             }
   1348 
   1349             if (mix->cur_fame == NULL)
   1350             {
   1351                 ret = mix_surfacepool_get(parent->surfacepool, &mix->cur_fame);
   1352                 if (ret != MIX_RESULT_SUCCESS)
   1353                 {
   1354                     LOG_E(
   1355                             "Failed to mix_surfacepool_get\n");
   1356                     return MIX_RESULT_FAIL;
   1357                 }
   1358             }
   1359 
   1360             LOG_V( "Get Surface Done\n");
   1361 
   1362 
   1363             VAImage src_image;
   1364             guint8 *pvbuf;
   1365             guint8 *dst_y;
   1366             guint8 *dst_uv;
   1367             int i,j;
   1368 
   1369             LOG_V(
   1370                     "map source data to surface\n");
   1371 
   1372             ret = mix_videoframe_get_frame_id(mix->cur_fame, &surface);
   1373             if (ret != MIX_RESULT_SUCCESS)
   1374             {
   1375                 LOG_E(
   1376                         "Failed to mix_videoframe_get_frame_id\n");
   1377                 return MIX_RESULT_FAIL;
   1378             }
   1379 
   1380 
   1381             LOG_I(
   1382                     "surface id = 0x%08x\n", (guint) surface);
   1383 
   1384             va_status = vaDeriveImage(va_display, surface, &src_image);
   1385             //need to destroy
   1386 
   1387             if (va_status != VA_STATUS_SUCCESS)
   1388             {
   1389                 LOG_E(
   1390                         "Failed to vaDeriveImage\n");
   1391                 return MIX_RESULT_FAIL;
   1392             }
   1393 
   1394             VAImage *image = &src_image;
   1395 
   1396             LOG_V( "vaDeriveImage Done\n");
   1397 
   1398 
   1399             va_status = vaMapBuffer (va_display, image->buf, (void **)&pvbuf);
   1400             if (va_status != VA_STATUS_SUCCESS)
   1401             {
   1402                 LOG_E( "Failed to vaMapBuffer\n");
   1403                 return MIX_RESULT_FAIL;
   1404             }
   1405 
   1406             LOG_V(
   1407                     "vaImage information\n");
   1408             LOG_I(
   1409                     "image->pitches[0] = %d\n", image->pitches[0]);
   1410             LOG_I(
   1411                     "image->pitches[1] = %d\n", image->pitches[1]);
   1412             LOG_I(
   1413                     "image->offsets[0] = %d\n", image->offsets[0]);
   1414             LOG_I(
   1415                     "image->offsets[1] = %d\n", image->offsets[1]);
   1416             LOG_I(
   1417                     "image->num_planes = %d\n", image->num_planes);
   1418             LOG_I(
   1419                     "image->width = %d\n", image->width);
   1420             LOG_I(
   1421                     "image->height = %d\n", image->height);
   1422 
   1423             LOG_I(
   1424                     "input buf size = %d\n", bufin->size);
   1425 
   1426             guint8 *inbuf = bufin->data;
   1427 
   1428             /*need to convert YUV420 to NV12*/
   1429             dst_y = pvbuf +image->offsets[0];
   1430 
   1431             for (i = 0; i < height; i ++) {
   1432                 memcpy (dst_y, inbuf + i * width, width);
   1433                 dst_y += image->pitches[0];
   1434             }
   1435 
   1436             dst_uv = pvbuf + image->offsets[1];
   1437 
   1438             for (i = 0; i < height / 2; i ++) {
   1439                 for (j = 0; j < width; j+=2) {
   1440                     dst_uv [j] = inbuf [width * height + i * width / 2 + j / 2];
   1441                     dst_uv [j + 1] =
   1442                         inbuf [width * height * 5 / 4 + i * width / 2 + j / 2];
   1443                 }
   1444                 dst_uv += image->pitches[1];
   1445             }
   1446 
   1447             vaUnmapBuffer(va_display, image->buf);
   1448             if (va_status != VA_STATUS_SUCCESS)
   1449             {
   1450                 LOG_E(
   1451                         "Failed to vaUnmapBuffer\n");
   1452                 return MIX_RESULT_FAIL;
   1453             }
   1454 
   1455             va_status = vaDestroyImage(va_display, src_image.image_id);
   1456             if (va_status != VA_STATUS_SUCCESS)
   1457             {
   1458                 LOG_E(
   1459                         "Failed to vaDestroyImage\n");
   1460                 return MIX_RESULT_FAIL;
   1461             }
   1462 
   1463             LOG_V(
   1464                     "Map source data to surface done\n");
   1465 
   1466         }
   1467 
   1468         else {//if (!parent->share_buf_mode)
   1469 
   1470             MixVideoFrame * frame = mix_videoframe_new();
   1471 
   1472             if (mix->ref_fame == NULL)
   1473             {
   1474                 ret = mix_videoframe_set_ci_frame_idx (frame, mix->surface_num - 1);
   1475 
   1476                 ret = mix_surfacepool_get_frame_with_ci_frameidx
   1477                     (parent->surfacepool, &mix->ref_fame, frame);
   1478                 if (ret != MIX_RESULT_SUCCESS)  //#ifdef SLEEP_SURFACE not used
   1479                 {
   1480                     LOG_E(
   1481                             "get reference surface from pool failed\n");
   1482                     return MIX_RESULT_FAIL;
   1483                 }
   1484             }
   1485 
   1486             if (mix->rec_fame == NULL)
   1487             {
   1488                 ret = mix_videoframe_set_ci_frame_idx (frame, mix->surface_num - 2);
   1489 
   1490                 ret = mix_surfacepool_get_frame_with_ci_frameidx
   1491                     (parent->surfacepool, &mix->rec_fame, frame);
   1492 
   1493                 if (ret != MIX_RESULT_SUCCESS)
   1494                 {
   1495                     LOG_E(
   1496                             "get recontructed surface from pool failed\n");
   1497                     return MIX_RESULT_FAIL;
   1498                 }
   1499             }
   1500 
   1501             //mix_videoframe_unref (mix->cur_fame);
   1502 
   1503             if (parent->need_display) {
   1504                 mix->cur_fame = NULL;
   1505             }
   1506 
   1507             if (mix->cur_fame == NULL)
   1508             {
   1509                 guint ci_idx;
   1510                 memcpy (&ci_idx, bufin->data, bufin->size);
   1511 
   1512                 LOG_I(
   1513                         "surface_num = %d\n", mix->surface_num);
   1514                 LOG_I(
   1515                         "ci_frame_idx = %d\n", ci_idx);
   1516 
   1517                 if (ci_idx > mix->surface_num - 2) {
   1518                     LOG_E(
   1519                             "the CI frame idx is too bigger than CI frame number\n");
   1520                     return MIX_RESULT_FAIL;
   1521                 }
   1522 
   1523 
   1524                 ret = mix_videoframe_set_ci_frame_idx (frame, ci_idx);
   1525 
   1526                 ret = mix_surfacepool_get_frame_with_ci_frameidx
   1527                     (parent->surfacepool, &mix->cur_fame, frame);
   1528 
   1529                 if (ret != MIX_RESULT_SUCCESS)
   1530                 {
   1531                     LOG_E(
   1532                             "get current working surface from pool failed\n");
   1533                     return MIX_RESULT_FAIL;
   1534                 }
   1535             }
   1536 
   1537             ret = mix_videoframe_get_frame_id(mix->cur_fame, &surface);
   1538 
   1539         }
   1540 
   1541         LOG_V( "vaBeginPicture\n");
   1542         LOG_I( "va_context = 0x%08x\n",(guint)va_context);
   1543         LOG_I( "surface = 0x%08x\n",(guint)surface);
   1544         LOG_I( "va_display = 0x%08x\n",(guint)va_display);
   1545 
   1546         va_status = vaBeginPicture(va_display, va_context, surface);
   1547         if (va_status != VA_STATUS_SUCCESS)
   1548         {
   1549             LOG_E( "Failed vaBeginPicture\n");
   1550             return MIX_RESULT_FAIL;
   1551         }
   1552 
   1553         LOG_V( "mix_videofmtenc_h264_send_seq_params\n");
   1554 
   1555         if (mix->encoded_frames == 0) {
   1556             mix_videofmtenc_h264_send_seq_params (mix);
   1557             if (ret != MIX_RESULT_SUCCESS)
   1558             {
   1559                 LOG_E(
   1560                         "Failed mix_videofmtenc_h264_send_seq_params\n");
   1561                 return MIX_RESULT_FAIL;
   1562             }
   1563         }
   1564 
   1565         ret = mix_videofmtenc_h264_send_picture_parameter (mix);
   1566 
   1567         if (ret != MIX_RESULT_SUCCESS)
   1568         {
   1569            LOG_E(
   1570                    "Failed mix_videofmtenc_h264_send_picture_parameter\n");
   1571            return MIX_RESULT_FAIL;
   1572         }
   1573 
   1574         ret = mix_videofmtenc_h264_send_slice_parameter (mix);
   1575         if (ret != MIX_RESULT_SUCCESS)
   1576         {
   1577             LOG_E(
   1578                     "Failed mix_videofmtenc_h264_send_slice_parameter\n");
   1579             return MIX_RESULT_FAIL;
   1580         }
   1581 
   1582         LOG_V( "before vaEndPicture\n");
   1583 
   1584         va_status = vaEndPicture (va_display, va_context);
   1585         if (va_status != VA_STATUS_SUCCESS)
   1586         {
   1587             LOG_E( "Failed vaEndPicture\n");
   1588             return MIX_RESULT_FAIL;
   1589         }
   1590 
   1591 
   1592         LOG_V( "vaSyncSurface\n");
   1593 
   1594         va_status = vaSyncSurface(va_display, surface);
   1595         if (va_status != VA_STATUS_SUCCESS)
   1596         {
   1597             LOG_E( "Failed vaSyncSurface\n");
   1598             return MIX_RESULT_FAIL;
   1599         }
   1600 
   1601 
   1602         LOG_V(
   1603                 "Start to get encoded data\n");
   1604 
   1605         /*get encoded data from the VA buffer*/
   1606         va_status = vaMapBuffer (va_display, mix->coded_buf, (void **)&buf);
   1607         if (va_status != VA_STATUS_SUCCESS)
   1608         {
   1609             LOG_E( "Failed vaMapBuffer\n");
   1610             return MIX_RESULT_FAIL;
   1611         }
   1612 
   1613         // first 4 bytes is the size of the buffer
   1614         memcpy (&(iovout->data_size), (void*)buf, 4);
   1615         //size = (guint*) buf;
   1616 
   1617         guint size = iovout->data_size + 100;
   1618 
   1619         iovout->buffer_size = size;
   1620 
   1621         //We will support two buffer mode, one is application allocates the buffer and passes to encode,
   1622         //the other is encode allocate memory
   1623 
   1624         if (iovout->data == NULL) { //means  app doesn't allocate the buffer, so _encode will allocate it.
   1625             iovout->data = g_malloc (size);  // In case we have lots of 0x000001 start code, and we replace them with 4 bytes length prefixed
   1626             if (iovout->data == NULL) {
   1627                 return MIX_RESULT_NO_MEMORY;
   1628             }
   1629         }
   1630 
   1631         if (mix->delimiter_type == MIX_DELIMITER_ANNEXB) {
   1632             memcpy (iovout->data, buf + 16, iovout->data_size); //parload is started from 17th byte
   1633             size = iovout->data_size;
   1634         } else {
   1635 
   1636             guint pos = 0;
   1637             guint zero_byte_count = 0;
   1638             guint prefix_length = 0;
   1639             guint8 nal_unit_type = 0;
   1640 	     guint8 * payload = buf + 16;
   1641 
   1642             while ((payload[pos++] == 0x00)) {
   1643                 zero_byte_count ++;
   1644                 if (pos >= iovout->data_size)  //to make sure the buffer to be accessed is valid
   1645                     break;
   1646             }
   1647 
   1648 	     nal_unit_type = (guint8)(payload[pos] & 0x1f);
   1649             prefix_length = zero_byte_count + 1;
   1650 
   1651             LOG_I ("nal_unit_type = %d\n", nal_unit_type);
   1652             LOG_I ("zero_byte_count = %d\n", zero_byte_count);
   1653 
   1654             if ((payload [pos - 1] & 0x01) && mix->slice_num == 1 && nal_unit_type == 1) {
   1655                 size =  iovout->data_size;
   1656                 iovout->data[0] = ((size - prefix_length) >> 24) & 0xff;
   1657                 iovout->data[1] = ((size - prefix_length) >> 16) & 0xff;
   1658                 iovout->data[2] = ((size - prefix_length) >> 8)  & 0xff;
   1659                 iovout->data[3] = (size - prefix_length)   & 0xff;
   1660                 // use 4 bytes to indicate the NALU length
   1661                 memcpy (iovout->data + 4, buf + 16 + prefix_length, size - prefix_length);
   1662                 LOG_V ("We only have one start code, copy directly\n");
   1663             }
   1664             else {
   1665                 ret = mix_videofmtenc_h264_AnnexB_to_length_prefixed (buf + 16, iovout->data_size, iovout->data, &size);
   1666                 if (ret != MIX_RESULT_SUCCESS)
   1667                 {
   1668                     LOG_E (
   1669                             "Failed mix_videofmtenc_h264_AnnexB_to_length_prefixed\n");
   1670                     return MIX_RESULT_FAIL;
   1671                 }
   1672             }
   1673         }
   1674 
   1675         iovout->data_size = size;
   1676         LOG_I(
   1677                 "out size is = %d\n", iovout->data_size);
   1678 
   1679         va_status = vaUnmapBuffer (va_display, mix->coded_buf);
   1680         if (va_status != VA_STATUS_SUCCESS)
   1681         {
   1682             LOG_E( "Failed vaUnmapBuffer\n");
   1683             return MIX_RESULT_FAIL;
   1684         }
   1685 
   1686         LOG_V( "get encoded data done\n");
   1687 #if 0
   1688         if (parent->drawable) {
   1689             va_status = vaPutSurface(va_display, surface, (Drawable)parent->drawable,
   1690                     0,0, width, height,
   1691                     0,0, width, height,
   1692                     NULL,0,0);
   1693         }
   1694 
   1695 #ifdef SHOW_SRC
   1696         else {
   1697 
   1698             va_status = vaPutSurface(va_display, surface, win,
   1699                     0,0, width, height,
   1700                     0,0, width, height,
   1701                     NULL,0,0);
   1702         }
   1703 #endif //SHOW_SRC
   1704 #endif
   1705 
   1706         VASurfaceStatus status;
   1707 
   1708         /*query the status of current surface*/
   1709         va_status = vaQuerySurfaceStatus(va_display, surface,  &status);
   1710         if (va_status != VA_STATUS_SUCCESS)
   1711         {
   1712             LOG_E(
   1713                     "Failed vaQuerySurfaceStatus\n");
   1714             return MIX_RESULT_FAIL;
   1715         }
   1716         mix->pic_skipped = status & VASurfaceSkipped;
   1717 
   1718         if (parent->need_display) {
   1719             ret = mix_framemanager_enqueue(parent->framemgr, mix->cur_fame);
   1720             if (ret != MIX_RESULT_SUCCESS)
   1721             {
   1722                 LOG_E(
   1723                         "Failed mix_framemanager_enqueue\n");
   1724                 return MIX_RESULT_FAIL;
   1725             }
   1726         }
   1727 
   1728 
   1729         /*update the reference surface and reconstructed surface */
   1730         if (!mix->pic_skipped) {
   1731             tmp_fame = mix->rec_fame;
   1732             mix->rec_fame= mix->ref_fame;
   1733             mix->ref_fame = tmp_fame;
   1734         }
   1735 
   1736 #if 0
   1737         if (mix->ref_fame != NULL)
   1738             mix_videoframe_unref (mix->ref_fame);
   1739         mix->ref_fame = mix->rec_fame;
   1740 
   1741         mix_videoframe_unref (mix->cur_fame);
   1742 #endif
   1743 
   1744         if (!(parent->need_display)) {
   1745             mix_videoframe_unref (mix->cur_fame);
   1746             mix->cur_fame = NULL;
   1747         }
   1748 
   1749         mix->encoded_frames ++;
   1750     }
   1751     else
   1752     {
   1753         LOG_E(
   1754                 "not H264 video encode Object\n");
   1755         return MIX_RESULT_FAIL;
   1756     }
   1757 
   1758 
   1759     LOG_V( "end\n");
   1760 
   1761     return MIX_RESULT_SUCCESS;
   1762 }
   1763 
   1764 MIX_RESULT mix_videofmtenc_h264_get_max_encoded_buf_size (
   1765         MixVideoFormatEnc *mix, guint *max_size)
   1766 {
   1767 
   1768     MixVideoFormatEnc *parent = NULL;
   1769 
   1770     if (mix == NULL || max_size == NULL)
   1771     {
   1772         LOG_E(
   1773                 "mix == NULL || max_size == NULL\n");
   1774             return MIX_RESULT_NULL_PTR;
   1775     }
   1776 
   1777     parent = MIX_VIDEOFORMATENC(mix);
   1778     MixVideoFormatEnc_H264 *self = MIX_VIDEOFORMATENC_H264(mix);
   1779 
   1780     LOG_V( "Begin\n");
   1781 
   1782     if (MIX_IS_VIDEOFORMATENC_H264(self)) {
   1783 
   1784         if (self->coded_buf_size > 0) {
   1785             *max_size = self->coded_buf_size;
   1786             LOG_V ("Already calculate the max encoded size, get the value directly");
   1787             return MIX_RESULT_SUCCESS;
   1788         }
   1789 
   1790         /*base on the rate control mode to calculate the defaule encoded buffer size*/
   1791         if (self->va_rcmode == VA_RC_NONE) {
   1792             self->coded_buf_size =
   1793                 (parent->picture_width* parent->picture_height * 400) / (16 * 16);
   1794             // set to value according to QP
   1795         }
   1796         else {
   1797             self->coded_buf_size = parent->bitrate/ 4;
   1798         }
   1799 
   1800         self->coded_buf_size =
   1801             max (self->coded_buf_size ,
   1802                     (parent->picture_width* parent->picture_height * 400) / (16 * 16));
   1803 
   1804         /*in case got a very large user input bit rate value*/
   1805         self->coded_buf_size =
   1806             min(self->coded_buf_size,
   1807                     (parent->picture_width * parent->picture_height * 1.5 * 8));
   1808         self->coded_buf_size =  (self->coded_buf_size + 15) &(~15);
   1809     }
   1810     else
   1811     {
   1812         LOG_E(
   1813                 "not H264 video encode Object\n");
   1814         return MIX_RESULT_FAIL;
   1815     }
   1816 
   1817     *max_size = self->coded_buf_size;
   1818 
   1819     return MIX_RESULT_SUCCESS;
   1820 }
   1821 
   1822 MIX_RESULT mix_videofmtenc_h264_AnnexB_to_length_prefixed (
   1823         guint8 * bufin, guint bufin_len, guint8* bufout, guint * bufout_len)
   1824 {
   1825 
   1826     guint pos = 0;
   1827     guint last_pos = 0;
   1828 
   1829     guint zero_byte_count = 0;
   1830     guint nal_size = 0;
   1831     guint prefix_length = 0;
   1832     guint size_copied = 0;
   1833     guint leading_zero_count = 0;
   1834 
   1835     if (bufin == NULL || bufout == NULL || bufout_len == NULL) {
   1836 
   1837         LOG_E(
   1838                 "bufin == NULL || bufout == NULL || bufout_len = NULL\n");
   1839         return MIX_RESULT_NULL_PTR;
   1840     }
   1841 
   1842     if (bufin_len <= 0 || *bufout_len <= 0) {
   1843         LOG_E(
   1844                 "bufin_len <= 0 || *bufout_len <= 0\n");
   1845         return MIX_RESULT_FAIL;
   1846     }
   1847 
   1848     LOG_V ("Begin\n");
   1849 
   1850     while ((bufin[pos++] == 0x00)) {
   1851         zero_byte_count ++;
   1852         if (pos >= bufin_len)  //to make sure the buffer to be accessed is valid
   1853             break;
   1854     }
   1855 
   1856     if (bufin[pos - 1] != 0x01 || zero_byte_count < 2)
   1857     {
   1858         LOG_E("The stream is not AnnexB format \n");
   1859         return MIX_RESULT_FAIL;	;  //not AnnexB, we won't process it
   1860     }
   1861 
   1862     zero_byte_count = 0;
   1863     last_pos = pos;
   1864 
   1865     while (pos < bufin_len) {
   1866 
   1867         while (bufin[pos++] == 0) {
   1868             zero_byte_count ++;
   1869             if (pos >= bufin_len) //to make sure the buffer to be accessed is valid
   1870                 break;
   1871         }
   1872 
   1873         if (bufin[pos - 1] == 0x01 && zero_byte_count >= 2) {
   1874             if (zero_byte_count == 2) {
   1875                 prefix_length = 3;
   1876             }
   1877             else {
   1878                 prefix_length = 4;
   1879                 leading_zero_count = zero_byte_count - 3;
   1880             }
   1881 
   1882             LOG_I("leading_zero_count = %d\n", leading_zero_count);
   1883 
   1884             nal_size = pos - last_pos - prefix_length - leading_zero_count;
   1885             if (nal_size < 0) {
   1886                 LOG_E ("something wrong in the stream\n");
   1887                 return MIX_RESULT_FAIL;	  //not AnnexB, we won't process it
   1888             }
   1889 
   1890             if (*bufout_len < (size_copied + nal_size + 4)) {
   1891                 LOG_E ("The length of destination buffer is too small\n");
   1892                 return MIX_RESULT_FAIL;
   1893             }
   1894 
   1895             LOG_I ("nal_size = %d\n", nal_size);
   1896 
   1897             /*We use 4 bytes length prefix*/
   1898             bufout [size_copied] = nal_size >> 24 & 0xff;
   1899             bufout [size_copied + 1] = nal_size >> 16 & 0xff;
   1900             bufout [size_copied + 2] = nal_size >> 8 & 0xff;
   1901             bufout [size_copied + 3] = nal_size  & 0xff;
   1902 
   1903             size_copied += 4;	//4 bytes length prefix
   1904             memcpy (bufout + size_copied, bufin + last_pos, nal_size);
   1905             size_copied += nal_size;
   1906 
   1907             LOG_I ("size_copied = %d\n", size_copied);
   1908 
   1909             zero_byte_count = 0;
   1910             leading_zero_count = 0;
   1911             last_pos = pos;
   1912         }
   1913 
   1914         else if (pos == bufin_len) {
   1915 
   1916             LOG_V ("Last NALU in this frame\n");
   1917 
   1918             nal_size = pos - last_pos;
   1919 
   1920             if (*bufout_len < (size_copied + nal_size + 4)) {
   1921                 LOG_E ("The length of destination buffer is too small\n");
   1922                 return MIX_RESULT_FAIL;
   1923             }
   1924 
   1925             /*We use 4 bytes length prefix*/
   1926             bufout [size_copied] = nal_size >> 24 & 0xff;
   1927             bufout [size_copied + 1] = nal_size >> 16 & 0xff;
   1928             bufout [size_copied + 2] = nal_size >> 8 & 0xff;
   1929             bufout [size_copied + 3] = nal_size  & 0xff;
   1930 
   1931             size_copied += 4;	//4 bytes length prefix
   1932             memcpy (bufout + size_copied, bufin + last_pos, nal_size);
   1933             size_copied += nal_size;
   1934 
   1935             LOG_I ("size_copied = %d\n", size_copied);
   1936         }
   1937 
   1938         else {
   1939             zero_byte_count = 0;
   1940             leading_zero_count = 0;
   1941         }
   1942 
   1943     }
   1944 
   1945     if (size_copied != *bufout_len) {
   1946         *bufout_len = size_copied;
   1947     }
   1948 
   1949     LOG_V ("End\n");
   1950 
   1951     return MIX_RESULT_SUCCESS;
   1952 
   1953 }
   1954 
   1955