Home | History | Annotate | Download | only in test
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2010, Code Aurora Forum. All rights reserved.
      3 
      4 Redistribution and use in source and binary forms, with or without
      5 modification, are permitted provided that the following conditions are met:
      6     * Redistributions of source code must retain the above copyright
      7       notice, this list of conditions and the following disclaimer.
      8     * Redistributions in binary form must reproduce the above copyright
      9       notice, this list of conditions and the following disclaimer in the
     10       documentation and/or other materials provided with the distribution.
     11     * Neither the name of Code Aurora nor
     12       the names of its contributors may be used to endorse or promote
     13       products derived from this software without specific prior written
     14       permission.
     15 
     16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 --------------------------------------------------------------------------*/
     28 #include "video_encoder_test.h"
     29 
     30 #define DEBUG_PRINT printf
     31 /************************************************************************/
     32 /*        #DEFINES                          */
     33 /************************************************************************/
     34 
     35 #define VOP_START_CODE 0x000001B6
     36 #define SHORT_HEADER_START_CODE 0x00008000
     37 #define H264_START_CODE         0x00000001
     38 
     39 /************************************************************************/
     40 /*        STATIC VARIABLES                          */
     41 /************************************************************************/
     42 
     43 static int Code_type;
     44 static int total_frames = 0;
     45 static unsigned int header_code = 0;
     46 static pthread_mutex_t read_lock;
     47 
     48 static unsigned int read_frame ( unsigned char *dataptr,unsigned int length,
     49                                  FILE * inputBufferFile
     50                                 );
     51 static unsigned clp2(unsigned x)
     52 {
     53         x = x - 1;
     54         x = x | (x >> 1);
     55         x = x | (x >> 2);
     56         x = x | (x >> 4);
     57         x = x | (x >> 8);
     58         x = x | (x >>16);
     59         return x + 1;
     60 }
     61 
     62 
     63 static void* video_thread (void *);
     64 static void* async_thread (void *);
     65 
     66 
     67 
     68 int main (int argc, char **argv)
     69 {
     70   struct video_encoder_context *encoder_context = NULL;
     71   char *file_name = NULL;
     72   FILE *file_ptr = NULL;
     73   int temp1 =0,temp2 =0;
     74   int error = 1;
     75   unsigned int i = 0;
     76 
     77   file_name = argv [1];
     78   file_ptr = fopen (file_name,"rb");
     79 
     80   if (file_ptr == NULL)
     81   {
     82     DEBUG_PRINT("\n File is not located ");
     83     return -1;
     84   }
     85 
     86 
     87   encoder_context = (struct video_encoder_context *) \
     88                    calloc (sizeof (struct video_encoder_context),1);
     89 
     90   encoder_context->outputBufferFile = NULL;
     91     encoder_context->inputBufferFile = NULL;
     92   encoder_context->video_driver_fd = -1;
     93 
     94   if (encoder_context == NULL)
     95   {
     96     return -1;
     97   }
     98 
     99   encoder_context->inputBufferFile = file_ptr;
    100   encoder_context->input_width = 176;
    101   encoder_context->input_height = 144;
    102   encoder_context->codectype = VEN_CODEC_MPEG4;
    103   encoder_context->fps_num = 60;
    104   encoder_context->fps_den = 2;
    105   encoder_context->inputformat = VEN_INPUTFMT_NV12;
    106   encoder_context->targetbitrate = 128000;
    107 
    108   file_ptr = fopen ("/data/output.m4v","wb");
    109   if (file_ptr == NULL)
    110   {
    111     DEBUG_PRINT("\n File can't be created");
    112     return -1;
    113   }
    114   encoder_context->outputBufferFile = file_ptr;
    115 
    116    switch (atoi(argv[2]))
    117    {
    118    case 0:
    119      DEBUG_PRINT("\n MPEG4 codec selected");
    120      encoder_context->codectype = VEN_CODEC_MPEG4;
    121      Code_type = 0;
    122      break;
    123    case 1:
    124      DEBUG_PRINT("\n H.263");
    125      encoder_context->codectype = VEN_CODEC_H263;
    126      Code_type = 0;
    127      break;
    128    case 2:
    129      DEBUG_PRINT("\n H.264");
    130      encoder_context->codectype = VEN_CODEC_H264;
    131      Code_type = 1;
    132      break;
    133    default:
    134      DEBUG_PRINT("\n Wrong codec type");
    135      error = -1;
    136      break;
    137    }
    138 
    139    if (error != -1)
    140    {
    141      temp1 = atoi(argv[3]);
    142      temp2 = atoi(argv[4]);
    143 
    144      if (((temp1%16) != 0) || ((temp2%16) != 0))
    145      {
    146        error = -1;
    147      }
    148      else
    149      {
    150       encoder_context->input_width = temp1;
    151       encoder_context->input_height = temp2;
    152      }
    153    }
    154 
    155    switch (atoi(argv[5]))
    156    {
    157    case 0:
    158      DEBUG_PRINT("\n No Sink");
    159      encoder_context->outputBufferFile = NULL;
    160      break;
    161    }
    162 
    163    if (error != -1)
    164    {
    165      encoder_context->targetbitrate = atoi (argv[6]);
    166    }
    167 
    168    if ( error != -1 && (init_encoder (encoder_context) == -1 ))
    169    {
    170       DEBUG_PRINT("\n Init decoder fails ");
    171       error = -1;
    172    }
    173    DEBUG_PRINT("\n Decoder open successfull");
    174 
    175 
    176    /*Allocate input and output buffers*/
    177    if (error != -1 && (allocate_buffer (0,encoder_context)== -1))
    178    {
    179      DEBUG_PRINT("\n Error in input Buffer allocation");
    180      error = -1;
    181    }
    182 
    183    if (error != -1 && (allocate_buffer (1,encoder_context)== -1))
    184    {
    185      DEBUG_PRINT("\n Error in output Buffer allocation");
    186      error = -1;
    187    }
    188 
    189 
    190    if (error != -1 && (start_encoding (encoder_context) == -1))
    191    {
    192      DEBUG_PRINT("\n Error in start decoding call");
    193      error = -1;
    194    }
    195 
    196    if (error != -1 && (stop_encoding (encoder_context) == -1))
    197    {
    198      DEBUG_PRINT("\n Error in stop decoding call");
    199      error = -1;
    200    }
    201 
    202    DEBUG_PRINT("\n De-init the decoder");
    203    if ((deinit_encoder (encoder_context) == -1))
    204    {
    205       error = -1;
    206    }
    207 
    208 
    209   (void)free_buffer (INPUT_BUFFER,encoder_context);
    210   (void)free_buffer (OUTPUT_BUFFER,encoder_context);
    211 
    212   if (encoder_context->inputBufferFile != NULL)
    213   {
    214    fclose (encoder_context->inputBufferFile);
    215   }
    216   if (encoder_context->outputBufferFile != NULL)
    217   {
    218     fclose (encoder_context->outputBufferFile);
    219   }
    220   DEBUG_PRINT ("\n Total Number of frames decoded %d",total_frames);
    221   DEBUG_PRINT("\n closing the driver");
    222   free (encoder_context);
    223 
    224   return error;
    225 }
    226 
    227 int init_encoder ( struct video_encoder_context *init_decode )
    228 {
    229   struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
    230   struct venc_basecfg basecfg;
    231   struct video_queue_context *queue_ptr = NULL;
    232   struct venc_ratectrlcfg ratecrl;
    233   pthread_mutexattr_t init_values;
    234   struct venc_profile profile;
    235   struct ven_profilelevel profilelevel;
    236 
    237   DEBUG_PRINT("\n Before calling the open");
    238 
    239   init_decode->video_driver_fd = open ("/dev/msm_vidc_enc", \
    240                      O_RDWR | O_NONBLOCK);
    241 
    242 
    243 
    244   if (init_decode->video_driver_fd < 0)
    245   {
    246     DEBUG_PRINT("\n Open failed");
    247     return -1;
    248   }
    249 
    250   basecfg.codectype = init_decode->codectype;
    251   basecfg.dvs_height = 0;
    252   basecfg.dvs_width = 0;
    253   basecfg.fps_den = init_decode->fps_den;
    254   basecfg.fps_num = init_decode->fps_num;
    255   basecfg.input_height = init_decode->input_height;
    256   basecfg.input_width = init_decode->input_width;
    257   basecfg.inputformat = init_decode->inputformat;
    258   basecfg.targetbitrate = init_decode->targetbitrate;
    259 
    260   /*Initialize Decoder with codec type and resolution*/
    261   ioctl_msg.inputparam = &basecfg;
    262   ioctl_msg.outputparam = NULL;
    263 
    264   if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_BASE_CFG,
    265          (void*)&ioctl_msg) < 0)
    266   {
    267     DEBUG_PRINT("\n Set base config type failed");
    268     return -1;
    269   }
    270 
    271   /*Initialize Decoder with codec type and resolution*/
    272   DEBUG_PRINT ("\n Switch off rate control");
    273   ioctl_msg.inputparam = &ratecrl;
    274   ioctl_msg.outputparam = NULL;
    275   ratecrl.rcmode = VEN_RC_OFF;
    276   if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_RATE_CTRL_CFG,
    277          (void*)&ioctl_msg) < 0)
    278   {
    279     DEBUG_PRINT("\n Set rate control failed");
    280     return -1;
    281   }
    282 
    283   if (basecfg.codectype == VEN_CODEC_H264)
    284   {
    285     DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High");
    286     ioctl_msg.inputparam = &profile;
    287     ioctl_msg.outputparam = NULL;
    288     profile.profile = VEN_PROFILE_H264_BASELINE;
    289     if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_CODEC_PROFILE,
    290            (void*)&ioctl_msg) < 0)
    291     {
    292       DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed");
    293       return -1;
    294     }
    295 
    296     DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High");
    297     ioctl_msg.inputparam = &profilelevel;
    298     ioctl_msg.outputparam = NULL;
    299     profilelevel.level = VEN_LEVEL_H264_1p1;
    300     if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_PROFILE_LEVEL,
    301            (void*)&ioctl_msg) < 0)
    302     {
    303       DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed");
    304       return -1;
    305     }
    306 
    307     if (basecfg.input_width > 720)
    308     {
    309       DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High");
    310       ioctl_msg.inputparam = &profile;
    311       ioctl_msg.outputparam = NULL;
    312       profile.profile = VEN_PROFILE_H264_HIGH;
    313       if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_CODEC_PROFILE,
    314              (void*)&ioctl_msg) < 0)
    315       {
    316         DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed");
    317         return -1;
    318       }
    319 
    320       DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High");
    321       ioctl_msg.inputparam = &profilelevel;
    322       ioctl_msg.outputparam = NULL;
    323       profilelevel.level = VEN_LEVEL_H264_3p1;
    324       if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_PROFILE_LEVEL,
    325              (void*)&ioctl_msg) < 0)
    326       {
    327         DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed");
    328         return -1;
    329       }
    330     }
    331   }
    332 
    333   DEBUG_PRINT("\n Query Input bufffer requirements");
    334   /*Get the Buffer requirements for input and output ports*/
    335 
    336 
    337 
    338   ioctl_msg.inputparam = NULL;
    339   ioctl_msg.outputparam = &init_decode->input_buffer;
    340 
    341   if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,
    342          (void*)&ioctl_msg) < 0)
    343   {
    344     DEBUG_PRINT("\n Requesting for input buffer requirements failed");
    345     return -1;
    346   }
    347 
    348   DEBUG_PRINT("\n input Size=%d min count =%d actual count = %d", \
    349               (int)init_decode->input_buffer.datasize,\
    350               (int)init_decode->input_buffer.mincount,\
    351               (int)init_decode->input_buffer.actualcount);
    352 
    353 
    354   ioctl_msg.inputparam = &init_decode->input_buffer;
    355   ioctl_msg.outputparam = NULL;
    356   init_decode->input_buffer.actualcount = init_decode->input_buffer.mincount + 2;
    357 
    358   if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,
    359          (void*)&ioctl_msg) < 0)
    360   {
    361     DEBUG_PRINT("\n Set Buffer Requirements Failed");
    362     return -1;
    363   }
    364 
    365 
    366   DEBUG_PRINT("\n Query output bufffer requirements");
    367   ioctl_msg.inputparam = NULL;
    368   ioctl_msg.outputparam = &init_decode->output_buffer;
    369 
    370   if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,
    371          (void*)&ioctl_msg) < 0)
    372   {
    373     DEBUG_PRINT("\n Requesting for output buffer requirements failed");
    374     return -1;
    375   }
    376 
    377   DEBUG_PRINT("\n output Size=%d min count =%d actual count = %d", \
    378               (int)init_decode->output_buffer.datasize,\
    379               (int)init_decode->output_buffer.mincount,\
    380               (int)init_decode->output_buffer.actualcount);
    381 
    382   /*Create Queue related data structures*/
    383   queue_ptr = &init_decode->queue_context;
    384   queue_ptr->commandq_size = 50;
    385   queue_ptr->dataq_size = 50;
    386 
    387   sem_init(&queue_ptr->sem_message,0, 0);
    388   sem_init(&init_decode->sem_synchronize,0, 0);
    389 
    390   pthread_mutexattr_init (&init_values);
    391   pthread_mutex_init (&queue_ptr->mutex,&init_values);
    392   pthread_mutex_init (&read_lock,&init_values);
    393   DEBUG_PRINT("\n create Queues");
    394   queue_ptr->ptr_cmdq = (struct video_msgq*) \
    395                         calloc (sizeof (struct video_msgq),
    396                   queue_ptr->commandq_size);
    397   queue_ptr->ptr_dataq = (struct video_msgq*) \
    398               calloc (sizeof (struct video_msgq),
    399                   queue_ptr->dataq_size
    400                   );
    401 
    402   if ( queue_ptr->ptr_cmdq == NULL ||
    403      queue_ptr->ptr_dataq == NULL
    404     )
    405   {
    406     return -1;
    407   }
    408   DEBUG_PRINT("\n create Threads");
    409   /*Create two threads*/
    410     if ( (pthread_create (&init_decode->videothread_id,NULL,video_thread,
    411             init_decode) < 0) ||
    412          (pthread_create (&init_decode->asyncthread_id,NULL,async_thread,
    413             init_decode) < 0)
    414     )
    415   {
    416     return -1;
    417   }
    418 
    419   return 1;
    420 }
    421 
    422 
    423 
    424 int free_buffer ( unsigned int  buffer_dir,
    425                   struct video_encoder_context *encoder_context
    426                  )
    427 {
    428   unsigned int buffercount = 0,i=0;
    429   struct venc_bufferpayload **ptemp = NULL;
    430 
    431   if (encoder_context == NULL)
    432   {
    433     return -1;
    434   }
    435 
    436   if (buffer_dir == INPUT_BUFFER && encoder_context->ptr_inputbuffer)
    437   {
    438       buffercount = encoder_context->input_buffer.actualcount;
    439       ptemp = encoder_context->ptr_inputbuffer;
    440 
    441     for (i=0;i<buffercount;i++)
    442     {
    443       if (ptemp [i])
    444       {
    445         if (ptemp [i]->fd != -1)
    446         {
    447           munmap ( ptemp [i]->pbuffer,ptemp [i]->maped_size);
    448           ptemp [i]->pbuffer = NULL;
    449           close (ptemp [i]->fd);
    450         }
    451         free (ptemp [i]);
    452         ptemp [i] = NULL;
    453       }
    454     }
    455     free (encoder_context->ptr_inputbuffer);
    456     encoder_context->ptr_inputbuffer = NULL;
    457   }
    458   else if ( buffer_dir == OUTPUT_BUFFER && encoder_context->ptr_outputbuffer )
    459   {
    460     buffercount = encoder_context->output_buffer.actualcount;
    461     ptemp = encoder_context->ptr_outputbuffer;
    462 
    463     if (ptemp)
    464     {
    465       for (i=0;i<buffercount;i++)
    466       {
    467         if (ptemp [i])
    468         {
    469           if (ptemp [i]->fd != -1)
    470           {
    471             munmap ( ptemp [i]->pbuffer,ptemp [i]->maped_size);
    472             ptemp [i]->pbuffer = NULL;
    473             close (ptemp [i]->fd);
    474           }
    475           free (ptemp [i]);
    476           ptemp [i] = NULL;
    477         }
    478       }
    479       free (ptemp);
    480       encoder_context->ptr_outputbuffer = NULL;
    481     }
    482   }
    483 
    484   return 1;
    485 }
    486 
    487 int allocate_buffer ( unsigned int buffer_dir,
    488                       struct video_encoder_context *encoder_context
    489                     )
    490 {
    491   struct venc_bufferpayload **ptemp = NULL;
    492   struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
    493   unsigned int buffercount = 0,i=0,alignedsize=0;
    494   unsigned int buffersize = 0;
    495 
    496   if ( encoder_context == NULL)
    497   {
    498     DEBUG_PRINT ("\nallocate_buffer: context is NULL");
    499     return -1;
    500   }
    501 
    502   if ( buffer_dir == INPUT_BUFFER )
    503   {
    504         /*Check if buffers are allocated*/
    505     if (encoder_context->ptr_inputbuffer != NULL)
    506     {
    507       DEBUG_PRINT ("\nallocate_buffer: encoder_context->ptr_inputbuffer is set");
    508       return -1;
    509     }
    510 
    511     buffercount = encoder_context->input_buffer.actualcount;
    512     alignedsize = encoder_context->input_buffer.alignment;
    513     buffersize = encoder_context->input_buffer.datasize;
    514     buffersize = (buffersize + alignedsize) & (~alignedsize);
    515   }
    516   else if (buffer_dir == OUTPUT_BUFFER)
    517   {
    518     /*Check if buffers are allocated*/
    519     if (encoder_context->ptr_outputbuffer != NULL)
    520     {
    521       DEBUG_PRINT ("\nallocate_buffer: Double allcoate output");
    522       return -1;
    523     }
    524 
    525     buffercount = encoder_context->output_buffer.actualcount;
    526     alignedsize = encoder_context->output_buffer.alignment;
    527     buffersize = encoder_context->output_buffer.datasize;
    528     buffersize = (buffersize + alignedsize) & (~alignedsize);
    529 
    530   }
    531   else
    532   {
    533     DEBUG_PRINT ("\nallocate_buffer: Wrong buffer directions");
    534     return -1;
    535   }
    536 
    537   ptemp = (struct venc_bufferpayload **)\
    538   calloc (sizeof (struct venc_bufferpayload *),buffercount);
    539 
    540   if (ptemp == NULL)
    541   {
    542     DEBUG_PRINT ("\nallocate_buffer: venc_bufferpayload failure");
    543     return -1;
    544   }
    545 
    546 
    547   if (buffer_dir == OUTPUT_BUFFER)
    548   {
    549     DEBUG_PRINT ("\nallocate_buffer: OUT");
    550     encoder_context->ptr_outputbuffer = ptemp;
    551   }
    552   else
    553   {
    554     DEBUG_PRINT ("\nallocate_buffer: IN");
    555     encoder_context->ptr_inputbuffer = ptemp;
    556   }
    557 
    558   /*Allocate buffer headers*/
    559   for (i=0; i< buffercount; i++)
    560   {
    561     ptemp [i] = (struct venc_bufferpayload*)\
    562     calloc (sizeof (struct venc_bufferpayload),1);
    563 
    564     if (ptemp [i] == NULL)
    565     {
    566       DEBUG_PRINT ("\nallocate_buffer: ptemp [i] calloc failure");
    567       return -1;
    568     }
    569     ptemp [i]->fd = -1;
    570   }
    571 
    572   for (i=0; i< buffercount; i++)
    573   {
    574     ptemp [i]->fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
    575 
    576     if (ptemp [i]->fd < 0)
    577     {
    578       DEBUG_PRINT ("\nallocate_buffer: open pmem failed");
    579       return -1;
    580     }
    581 
    582     ptemp [i]->pbuffer = mmap(NULL,clp2(buffersize),PROT_READ|PROT_WRITE,
    583                                  MAP_SHARED,ptemp [i]->fd,0);
    584     DEBUG_PRINT ("\n pmem fd = %d virt addr = %p",ptemp [i]->fd,\
    585                   ptemp [i]->pbuffer);
    586     if (ptemp [i]->pbuffer == MAP_FAILED)
    587     {
    588       ptemp [i]->pbuffer = NULL;
    589       DEBUG_PRINT ("\nallocate_buffer: MMAP failed");
    590       return -1;
    591     }
    592     ptemp [i]->nsize = buffersize;
    593     ptemp [i]->maped_size = clp2 (buffersize);
    594 
    595     ioctl_msg.inputparam  = ptemp [i];
    596     ioctl_msg.outputparam = NULL;
    597 
    598     if (buffer_dir == OUTPUT_BUFFER)
    599     {
    600       if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER,
    601            &ioctl_msg) < 0)
    602       {
    603         DEBUG_PRINT ("\nallocate_buffer: Set Output Buffer IOCTL failed");
    604         return -1;
    605       }
    606     }
    607     else
    608     {
    609       if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_SET_INPUT_BUFFER,
    610            &ioctl_msg) < 0)
    611       {
    612         DEBUG_PRINT ("\nallocate_buffer: Set input Buffer IOCTL failed");
    613         return -1;
    614       }
    615     }
    616 
    617   }
    618   DEBUG_PRINT ("\nallocate_buffer: Success");
    619   return 1;
    620 }
    621 
    622 
    623 
    624 int start_encoding (struct video_encoder_context *encoder_context)
    625 {
    626   struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
    627   struct venc_buffer enc_buffer;
    628   unsigned int i = 0;
    629   unsigned int data_len =0;
    630 
    631 
    632   if (encoder_context == NULL)
    633   {
    634     return -1;
    635   }
    636 
    637   if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_CMD_START,
    638          NULL) < 0)
    639   {
    640     DEBUG_PRINT("\n Start failed");
    641     return -1;
    642   }
    643 
    644   DEBUG_PRINT("\n Start Issued successfully waiting for Start Done");
    645   /*Wait for Start command response*/
    646   sem_wait (&encoder_context->sem_synchronize);
    647 
    648   /*Push output Buffers*/
    649   i = 0;
    650   while (i < encoder_context->output_buffer.actualcount)
    651   {
    652     enc_buffer.clientdata = (void *)encoder_context->ptr_outputbuffer [i];
    653     enc_buffer.flags = 0;
    654     enc_buffer.size = encoder_context->ptr_outputbuffer [i]->nsize;
    655     enc_buffer.len = 0;
    656     enc_buffer.ptrbuffer = encoder_context->ptr_outputbuffer [i]->pbuffer;
    657     enc_buffer.offset = 0;
    658     enc_buffer.timestamp = 0;
    659 
    660     DEBUG_PRINT ("\n Client Data on output = %p",(void *)enc_buffer.clientdata);
    661     ioctl_msg.inputparam = &enc_buffer;
    662     ioctl_msg.outputparam = NULL;
    663 
    664     if (ioctl (encoder_context->video_driver_fd,
    665            VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0)
    666     {
    667       DEBUG_PRINT("\n fill output frame failed");
    668       return -1;
    669     }
    670     i++;
    671   }
    672 
    673 
    674   /*push input buffers*/
    675   i = 0;
    676   while (i < encoder_context->input_buffer.actualcount)
    677   {
    678     DEBUG_PRINT("\n Read  Frame from File");
    679 
    680     enc_buffer.clientdata = (void *)encoder_context->ptr_inputbuffer [i];
    681     enc_buffer.flags = 0;
    682     enc_buffer.size = encoder_context->ptr_inputbuffer [i]->nsize;
    683     enc_buffer.len = 0;
    684     enc_buffer.ptrbuffer = encoder_context->ptr_inputbuffer [i]->pbuffer;
    685     enc_buffer.offset = 0;
    686     enc_buffer.timestamp = total_frames *
    687                 ((encoder_context->fps_den * 1000000)/encoder_context->fps_num);
    688     enc_buffer.len = (encoder_context->input_height *
    689                      encoder_context->input_width *3)/2;
    690     data_len = read_frame ( enc_buffer.ptrbuffer,
    691                             enc_buffer.len,
    692                             encoder_context->inputBufferFile);
    693     if (data_len == 0)
    694     {
    695       DEBUG_PRINT("\n Length is zero error");
    696       return -1;
    697     }
    698     enc_buffer.len = data_len;
    699     DEBUG_PRINT("\n Read  Frame from File szie = %d",(int)data_len);
    700 
    701     DEBUG_PRINT ("\n Client Data on output = %p",(void *)enc_buffer.clientdata);
    702     ioctl_msg.inputparam = &enc_buffer;
    703     ioctl_msg.outputparam = NULL;
    704 
    705     if (ioctl (encoder_context->video_driver_fd,
    706            VEN_IOCTL_CMD_ENCODE_FRAME,&ioctl_msg) < 0)
    707     {
    708       DEBUG_PRINT("\n Encode input frame failed");
    709       return -1;
    710     }
    711     total_frames++;
    712     i++;
    713   }
    714   DEBUG_PRINT ("\n Wait for EOS");
    715   /*Wait for EOS or Error condition*/
    716   sem_wait (&encoder_context->sem_synchronize);
    717   DEBUG_PRINT ("\n Reached EOS");
    718 
    719   return 1;
    720 }
    721 
    722 int stop_encoding  (struct video_encoder_context *encoder_context)
    723 {
    724   struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
    725   struct venc_bufferflush buffer_flush;
    726 
    727   if (encoder_context == NULL)
    728   {
    729     return -1;
    730   }
    731   buffer_flush.flush_mode = VEN_FLUSH_INPUT;
    732   ioctl_msg.inputparam = &buffer_flush;
    733   ioctl_msg.outputparam = NULL;
    734 
    735   if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_FLUSH,
    736          &ioctl_msg) < 0)
    737   {
    738     DEBUG_PRINT("\n Flush input failed");
    739   }
    740   else
    741   {
    742        sem_wait (&encoder_context->sem_synchronize);
    743   }
    744 
    745   buffer_flush.flush_mode = VEN_FLUSH_OUTPUT;
    746   ioctl_msg.inputparam = &buffer_flush;
    747   ioctl_msg.outputparam = NULL;
    748 
    749   if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_FLUSH,
    750             &ioctl_msg) < 0)
    751   {
    752     DEBUG_PRINT("\n Flush output failed");
    753   }
    754   else
    755   {
    756      sem_wait (&encoder_context->sem_synchronize);
    757   }
    758 
    759   DEBUG_PRINT("\n Stop VEN_IOCTL_CMD_STOP");
    760   if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_STOP,NULL) < 0)
    761   {
    762     DEBUG_PRINT("\n Stop failed");
    763   }
    764   else
    765   {
    766      sem_wait (&encoder_context->sem_synchronize);
    767   }
    768   return 1;
    769 }
    770 
    771 int deinit_encoder (struct video_encoder_context *init_decode)
    772 {
    773   if (init_decode == NULL)
    774   {
    775     return -1;
    776   }
    777 
    778   /*Close the driver*/
    779   if (init_decode->video_driver_fd != -1)
    780   {
    781     close (init_decode->video_driver_fd);
    782   }
    783 
    784   if (init_decode->queue_context.ptr_cmdq)
    785   {
    786     free (init_decode->queue_context.ptr_cmdq);
    787     init_decode->queue_context.ptr_cmdq = NULL;
    788   }
    789 
    790   if (init_decode->queue_context.ptr_dataq)
    791   {
    792     free (init_decode->queue_context.ptr_dataq);
    793     init_decode->queue_context.ptr_dataq = NULL;
    794   }
    795 
    796   sem_destroy (&init_decode->queue_context.sem_message);
    797   sem_destroy (&init_decode->sem_synchronize);
    798 
    799   pthread_mutex_destroy(&init_decode->queue_context.mutex);
    800   pthread_mutex_destroy (&read_lock);
    801 
    802   return 1;
    803 }
    804 
    805 static void* video_thread (void *context)
    806 {
    807    struct video_encoder_context *encoder_context = NULL;
    808    struct video_msgq *queueitem = NULL;
    809    struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
    810    struct venc_bufferpayload *tempbuffer = NULL;
    811    struct venc_buffer enc_buffer;
    812    unsigned int data_len =0;
    813 
    814 
    815    if (context == NULL)
    816    {
    817      DEBUG_PRINT("\n video thread recieved NULL context");
    818      return NULL;
    819    }
    820    encoder_context = (struct video_encoder_context *) context;
    821 
    822    /* Thread function which will accept commands from async thread
    823     * or main thread
    824    */
    825    while (1)
    826    {
    827       queueitem = queue_get_cmd (&encoder_context ->queue_context);
    828       if (queueitem != NULL)
    829       {
    830         switch (queueitem->cmd)
    831         {
    832         case VEN_MSG_START:
    833           DEBUG_PRINT("\n recived start done command");
    834             sem_post (&encoder_context->sem_synchronize);
    835           break;
    836 
    837         case VEN_MSG_STOP:
    838           DEBUG_PRINT("\n recieved stop done");
    839           sem_post (&encoder_context->sem_synchronize);
    840           break;
    841 
    842         case VEN_MSG_INPUT_BUFFER_DONE:
    843 
    844           tempbuffer = (struct venc_bufferpayload *)queueitem->clientdata;
    845           if (tempbuffer == NULL)
    846           {
    847             DEBUG_PRINT("\n FATAL ERROR input buffer address is bad");
    848             sem_post (&encoder_context->sem_synchronize);
    849             break;
    850           }
    851           tempbuffer->filled_len = (encoder_context->input_height *
    852                              encoder_context->input_width *3)/2;
    853 
    854           data_len = read_frame ( tempbuffer->pbuffer,
    855                                   tempbuffer->filled_len,
    856                                   encoder_context->inputBufferFile);
    857 
    858           if (data_len == 0)
    859           {
    860             DEBUG_PRINT ("\n End of stream reached");
    861             sem_post (&encoder_context->sem_synchronize);
    862             break;
    863           }
    864           enc_buffer.clientdata = (void *)tempbuffer;
    865           enc_buffer.flags = 0;
    866           enc_buffer.ptrbuffer = tempbuffer->pbuffer;
    867           enc_buffer.size = tempbuffer->nsize;
    868           enc_buffer.len = tempbuffer->filled_len;
    869           enc_buffer.offset = 0;
    870           enc_buffer.timestamp = total_frames *
    871                 ((encoder_context->fps_den * 1000000)/encoder_context->fps_num);
    872 
    873           /*TODO: Time stamp needs to be updated*/
    874           ioctl_msg.inputparam = &enc_buffer;
    875           ioctl_msg.outputparam = NULL;
    876           total_frames++;
    877           if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_ENCODE_FRAME,
    878                &ioctl_msg) < 0)
    879           {
    880             DEBUG_PRINT("\n Decoder frame failed");
    881             sem_post (&encoder_context->sem_synchronize);
    882           }
    883           DEBUG_PRINT("\n Input buffer done send next buffer current value = %d",\
    884                       total_frames);
    885           break;
    886 
    887         case VEN_MSG_OUTPUT_BUFFER_DONE:
    888 
    889           tempbuffer = (struct venc_bufferpayload *)queueitem->clientdata;
    890           if (tempbuffer == NULL)
    891           {
    892             DEBUG_PRINT("\n FATAL ERROR input buffer address is bad");
    893             sem_post (&encoder_context->sem_synchronize);
    894             break;
    895           }
    896 
    897          if (encoder_context->outputBufferFile != NULL)
    898          {
    899            fwrite (tempbuffer->pbuffer,1,tempbuffer->filled_len,
    900                 encoder_context->outputBufferFile);
    901          }
    902 
    903 
    904          DEBUG_PRINT("\n recieved output buffer consume outbuffer");
    905          DEBUG_PRINT("\nValues outputbuffer->bufferaddr = %p",\
    906                      tempbuffer->pbuffer);
    907          enc_buffer.clientdata = (void *)tempbuffer;
    908          enc_buffer.flags = 0;
    909          enc_buffer.size = tempbuffer->nsize;
    910          enc_buffer.len = 0;
    911          enc_buffer.ptrbuffer = tempbuffer->pbuffer;
    912          enc_buffer.offset = 0;
    913          enc_buffer.timestamp = 0;
    914 
    915          ioctl_msg.inputparam = &enc_buffer;
    916          ioctl_msg.outputparam = NULL;
    917 
    918          if (ioctl (encoder_context->video_driver_fd,
    919               VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0)
    920          {
    921            DEBUG_PRINT("\n Decoder frame failed");
    922            return NULL;
    923          }
    924 
    925          break;
    926 
    927         case VEN_MSG_FLUSH_INPUT_DONE:
    928           DEBUG_PRINT("\n Flush input complete");
    929           sem_post (&encoder_context->sem_synchronize);
    930           break;
    931 
    932         case VEN_MSG_FLUSH_OUPUT_DONE:
    933           DEBUG_PRINT("\n Flush output complete");
    934           sem_post (&encoder_context->sem_synchronize);
    935           break;
    936          }
    937       }
    938       else
    939       {
    940         DEBUG_PRINT("\n Error condition recieved NULL from Queue");
    941       }
    942 
    943       if (queueitem->cmd == VEN_MSG_STOP)
    944       {
    945         DEBUG_PRINT("\n Playback has ended thread will exit");
    946         return NULL;
    947       }
    948    }
    949 }
    950 
    951 static void* async_thread (void *context)
    952 {
    953   struct video_encoder_context *encoder_context = NULL;
    954   struct video_msgq queueitem ;
    955   struct venc_msg venc_msg;
    956   struct venc_bufferpayload *tempbuffer = NULL;
    957   struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
    958   int result = -1;
    959 
    960   if (context == NULL)
    961   {
    962     DEBUG_PRINT("\n aynsc thread recieved NULL context");
    963     return NULL;
    964   }
    965   encoder_context = (struct video_encoder_context *) context;
    966   DEBUG_PRINT("\n Entering the async thread");
    967 
    968   while (1)
    969   {
    970     ioctl_msg.inputparam = NULL;
    971     ioctl_msg.outputparam = (void*)&venc_msg;
    972     DEBUG_PRINT ("\n Sizeof venc_msginfo = %d ",sizeof (venc_msg));
    973     DEBUG_PRINT("\n Address of Venc msg in async thread %p",\
    974                 ioctl_msg.outputparam);
    975     if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_CMD_READ_NEXT_MSG,\
    976          (void*)&ioctl_msg) < 0)
    977     {
    978       DEBUG_PRINT("\n Error in ioctl read next msg");
    979     }
    980     else
    981     {
    982       switch (venc_msg.msgcode)
    983       {
    984       case VEN_MSG_START:
    985       case VEN_MSG_STOP:
    986       case VEN_MSG_INDICATION:
    987         DEBUG_PRINT("\nSTOP/START Indiacation");
    988         queueitem.cmd = venc_msg.msgcode;
    989         queueitem.status = venc_msg.statuscode;
    990         queueitem.clientdata = NULL;
    991         break;
    992 
    993       case VEN_MSG_INPUT_BUFFER_DONE:
    994         DEBUG_PRINT("\nINPUT buffer done Indiacation");
    995         queueitem.cmd = venc_msg.msgcode;
    996         queueitem.status = venc_msg.statuscode;
    997         queueitem.clientdata = (void *)venc_msg.buf.clientdata;
    998         DEBUG_PRINT("\nInput Client data pointer is %p",queueitem.clientdata);
    999         tempbuffer = (struct venc_bufferpayload *) queueitem.clientdata;
   1000         DEBUG_PRINT ("\n Input Address of tempbuffer %p",tempbuffer);
   1001         tempbuffer->filled_len = venc_msg.buf.len;
   1002         DEBUG_PRINT ("\n Input value of tempbuffer tempbuffer->filled_len %d",(int)tempbuffer->filled_len);
   1003         break;
   1004       case VEN_MSG_OUTPUT_BUFFER_DONE:
   1005         DEBUG_PRINT("\nOUPUT buffer done Indiacation");
   1006         queueitem.cmd = venc_msg.msgcode;
   1007         queueitem.status = venc_msg.statuscode;
   1008         queueitem.clientdata = (void *)venc_msg.buf.clientdata;
   1009         DEBUG_PRINT("\nOutput Client data pointer is %p",queueitem.clientdata);
   1010         tempbuffer = (struct venc_bufferpayload *) queueitem.clientdata;
   1011         DEBUG_PRINT ("\n Output Address of tempbuffer %p",tempbuffer);
   1012         tempbuffer->filled_len = venc_msg.buf.len;
   1013         DEBUG_PRINT ("\n Output value of tempbuffer tempbuffer->filled_len %d",(int)tempbuffer->filled_len);
   1014         break;
   1015 
   1016       default:
   1017         DEBUG_PRINT("\nIn Default of get next message %d",(int)venc_msg.msgcode);
   1018         queueitem.cmd = venc_msg.msgcode;
   1019         queueitem.status = venc_msg.statuscode;
   1020         queueitem.clientdata = NULL;
   1021         break;
   1022       }
   1023       result = queue_post_cmdq (&encoder_context->queue_context,&queueitem);
   1024       while (result == 0)
   1025       {
   1026          result = queue_post_cmdq (&encoder_context->queue_context,&queueitem);
   1027       }
   1028 
   1029       if (result == -1)
   1030       {
   1031         DEBUG_PRINT("\n FATAL ERROR WITH Queue");
   1032       }
   1033     }
   1034     if (venc_msg.msgcode == VEN_MSG_STOP)
   1035     {
   1036       /*Thread can exit at this point*/
   1037       return NULL;
   1038     }
   1039   }
   1040 }
   1041 
   1042 
   1043 static unsigned int read_frame (unsigned char *dataptr, unsigned int length,
   1044                                 FILE * inputBufferFile)
   1045 {
   1046 
   1047   unsigned int readOffset = 0;
   1048   int bytes_read = 0;
   1049   unsigned int code = 0;
   1050   int found = 0;
   1051 
   1052   DEBUG_PRINT ("\n Inside the readframe");
   1053 
   1054   if (dataptr == NULL && length == 0)
   1055   {
   1056     DEBUG_PRINT ("\n dataptr = %p length = %d",dataptr,(int)length);
   1057     return 0;
   1058   }
   1059 
   1060   pthread_mutex_lock(&read_lock);
   1061   bytes_read = fread(&dataptr[readOffset],1,length,inputBufferFile);
   1062   pthread_mutex_unlock(&read_lock);
   1063 
   1064   return bytes_read;
   1065 }
   1066