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