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 "decoder_driver_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 int Read_Buffer_From_DAT_File( unsigned char *dataptr, unsigned int length,
     52                                       FILE * inputBufferFile
     53                                      );
     54 
     55 static unsigned clp2(unsigned x)
     56 {
     57         x = x - 1;
     58         x = x | (x >> 1);
     59         x = x | (x >> 2);
     60         x = x | (x >> 4);
     61         x = x | (x >> 8);
     62         x = x | (x >>16);
     63         return x + 1;
     64 }
     65 
     66 static void* video_thread (void *);
     67 static void* async_thread (void *);
     68 
     69 int main (int argc, char **argv)
     70 {
     71   struct video_decoder_context *decoder_context = NULL;
     72   char *file_name = NULL;
     73   FILE *file_ptr = NULL;
     74   int temp1 =0,temp2 =0;
     75   int error = 1;
     76   unsigned int i = 0;
     77 
     78   file_name = argv [1];
     79   file_ptr = fopen (file_name,"rb");
     80 
     81   if (file_ptr == NULL)
     82   {
     83     DEBUG_PRINT("\n File is not located ");
     84     return -1;
     85   }
     86 
     87 
     88   decoder_context = (struct video_decoder_context *) \
     89                    calloc (sizeof (struct video_decoder_context),1);
     90 
     91   decoder_context->outputBufferFile = NULL;
     92     decoder_context->inputBufferFile = NULL;
     93   decoder_context->video_driver_fd = -1;
     94 
     95   if (decoder_context == NULL)
     96   {
     97     return -1;
     98   }
     99 
    100   decoder_context->inputBufferFile = file_ptr;
    101 
    102   file_ptr = fopen ("/data/output.yuv","wb");
    103   if (file_ptr == NULL)
    104   {
    105     DEBUG_PRINT("\n File can't be created");
    106     return -1;
    107   }
    108   decoder_context->outputBufferFile = file_ptr;
    109 
    110    switch (atoi(argv[2]))
    111    {
    112    case 0:
    113      DEBUG_PRINT("\n MPEG4 codec selected");
    114      decoder_context->decoder_format = VDEC_CODECTYPE_MPEG4;
    115      Code_type = 0;
    116      break;
    117    case 1:
    118      DEBUG_PRINT("\n H.263");
    119      decoder_context->decoder_format = VDEC_CODECTYPE_H263;
    120      Code_type = 0;
    121      break;
    122    case 2:
    123      DEBUG_PRINT("\n H.264");
    124      decoder_context->decoder_format = VDEC_CODECTYPE_H264;
    125      Code_type = 1;
    126      break;
    127    default:
    128      DEBUG_PRINT("\n Wrong codec type");
    129      error = -1;
    130      break;
    131    }
    132 
    133    if (error != -1)
    134    {
    135      temp1 = atoi(argv[3]);
    136      temp2 = atoi(argv[4]);
    137 
    138      if (((temp1%16) != 0) || ((temp2%16) != 0))
    139      {
    140        error = -1;
    141      }
    142      else
    143      {
    144       decoder_context->video_resoultion.frame_height = temp1;
    145             decoder_context->video_resoultion.frame_width = temp2;
    146      }
    147    }
    148 
    149    switch (atoi(argv[5]))
    150    {
    151    case 0:
    152      DEBUG_PRINT("\n No Sink");
    153      decoder_context->outputBufferFile = NULL;
    154      break;
    155    }
    156 
    157    if ( error != -1 && (init_decoder (decoder_context) == -1 ))
    158    {
    159       DEBUG_PRINT("\n Init decoder fails ");
    160       error = -1;
    161    }
    162    DEBUG_PRINT("\n Decoder open successfull");
    163 
    164 
    165    /*Allocate input and output buffers*/
    166    if (error != -1 && (allocate_buffer (VDEC_BUFFER_TYPE_INPUT,
    167                       decoder_context)== -1))
    168    {
    169      DEBUG_PRINT("\n Error in input Buffer allocation");
    170      error = -1;
    171    }
    172 
    173    if (error != -1 && (allocate_buffer (VDEC_BUFFER_TYPE_OUTPUT,
    174                       decoder_context)== -1))
    175    {
    176      DEBUG_PRINT("\n Error in output Buffer allocation");
    177      error = -1;
    178    }
    179 
    180 
    181    if (error != -1 && (start_decoding (decoder_context) == -1))
    182    {
    183      DEBUG_PRINT("\n Error in start decoding call");
    184      error = -1;
    185    }
    186 
    187    if (error != -1 && (stop_decoding (decoder_context) == -1))
    188    {
    189      DEBUG_PRINT("\n Error in stop decoding call");
    190      error = -1;
    191    }
    192 
    193    DEBUG_PRINT("\n De-init the decoder");
    194    if ((deinit_decoder (decoder_context) == -1))
    195    {
    196       error = -1;
    197    }
    198 
    199 
    200   (void)free_buffer (VDEC_BUFFER_TYPE_INPUT,decoder_context);
    201   (void)free_buffer (VDEC_BUFFER_TYPE_OUTPUT,decoder_context);
    202 
    203   if (decoder_context->inputBufferFile != NULL)
    204   {
    205    fclose (decoder_context->inputBufferFile);
    206   }
    207   if (decoder_context->outputBufferFile != NULL)
    208   {
    209     fclose (decoder_context->outputBufferFile);
    210   }
    211   DEBUG_PRINT ("\n Total Number of frames decoded %d",total_frames);
    212   DEBUG_PRINT("\n closing the driver");
    213   free (decoder_context);
    214 
    215   return error;
    216 }
    217 
    218 int init_decoder ( struct video_decoder_context *init_decode )
    219 {
    220   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
    221   struct video_queue_context *queue_ptr = NULL;
    222   enum vdec_output_fromat output_format = VDEC_YUV_FORMAT_NV12;
    223   pthread_mutexattr_t init_values;
    224 
    225   DEBUG_PRINT("\n Before calling the open");
    226 
    227   init_decode->video_driver_fd = open ("/dev/msm_vidc_dec", \
    228                      O_RDWR | O_NONBLOCK);
    229 
    230 
    231 
    232   if (init_decode->video_driver_fd < 0)
    233   {
    234     DEBUG_PRINT("\n Open failed");
    235     return -1;
    236   }
    237 
    238 
    239   /*Initialize Decoder with codec type and resolution*/
    240   ioctl_msg.inputparam = &init_decode->decoder_format;
    241   ioctl_msg.outputparam = NULL;
    242 
    243   if (ioctl (init_decode->video_driver_fd,VDEC_IOCTL_SET_CODEC,
    244          (void*)&ioctl_msg) < 0)
    245   {
    246     DEBUG_PRINT("\n Set codec type failed");
    247     return -1;
    248   }
    249 
    250   /*Set the output format*/
    251   ioctl_msg.inputparam = &output_format;
    252   ioctl_msg.outputparam = NULL;
    253 
    254   if (ioctl (init_decode->video_driver_fd,VDEC_IOCTL_SET_OUTPUT_FORMAT,
    255          (void*)&ioctl_msg) < 0)
    256   {
    257     DEBUG_PRINT("\n Set output format failed");
    258     return -1;
    259   }
    260 
    261   ioctl_msg.inputparam = &init_decode->video_resoultion;
    262   ioctl_msg.outputparam = NULL;
    263 
    264   if (ioctl (init_decode->video_driver_fd,VDEC_IOCTL_SET_PICRES,
    265          (void*)&ioctl_msg) < 0)
    266   {
    267     DEBUG_PRINT("\n Set Resolution failed");
    268     return -1;
    269   }
    270   DEBUG_PRINT("\n After Set Resolution");
    271 
    272   DEBUG_PRINT("\n Query Input bufffer requirements");
    273   /*Get the Buffer requirements for input and output ports*/
    274 
    275   init_decode->input_buffer.buffer_type = VDEC_BUFFER_TYPE_INPUT;
    276   ioctl_msg.inputparam = NULL;
    277   ioctl_msg.outputparam = &init_decode->input_buffer;
    278 
    279   if (ioctl (init_decode->video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ,
    280          (void*)&ioctl_msg) < 0)
    281   {
    282     DEBUG_PRINT("\n Requesting for input buffer requirements failed");
    283     return -1;
    284   }
    285 
    286   DEBUG_PRINT("\n input Size=%d min count =%d actual count = %d", \
    287               init_decode->input_buffer.buffer_size,\
    288               init_decode->input_buffer.mincount,\
    289               init_decode->input_buffer.actualcount);
    290 
    291 
    292   init_decode->input_buffer.buffer_type = VDEC_BUFFER_TYPE_INPUT;
    293   ioctl_msg.inputparam = &init_decode->input_buffer;
    294   ioctl_msg.outputparam = NULL;
    295   init_decode->input_buffer.actualcount = init_decode->input_buffer.mincount + 2;
    296 
    297   if (ioctl (init_decode->video_driver_fd,VDEC_IOCTL_SET_BUFFER_REQ,
    298          (void*)&ioctl_msg) < 0)
    299   {
    300     DEBUG_PRINT("\n Set Buffer Requirements Failed");
    301     return -1;
    302   }
    303 
    304 
    305   DEBUG_PRINT("\n Query output bufffer requirements");
    306   init_decode->output_buffer.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
    307   ioctl_msg.inputparam = NULL;
    308   ioctl_msg.outputparam = &init_decode->output_buffer;
    309 
    310   if (ioctl (init_decode->video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ,
    311          (void*)&ioctl_msg) < 0)
    312   {
    313     DEBUG_PRINT("\n Requesting for output buffer requirements failed");
    314     return -1;
    315   }
    316 
    317   DEBUG_PRINT("\n output Size=%d min count =%d actual count = %d", \
    318               init_decode->output_buffer.buffer_size,\
    319               init_decode->output_buffer.mincount,\
    320               init_decode->output_buffer.actualcount);
    321 
    322   /*Create Queue related data structures*/
    323   queue_ptr = &init_decode->queue_context;
    324   queue_ptr->commandq_size = 50;
    325   queue_ptr->dataq_size = 50;
    326 
    327   sem_init(&queue_ptr->sem_message,0, 0);
    328   sem_init(&init_decode->sem_synchronize,0, 0);
    329 
    330   pthread_mutexattr_init (&init_values);
    331   pthread_mutex_init (&queue_ptr->mutex,&init_values);
    332   pthread_mutex_init (&read_lock,&init_values);
    333   DEBUG_PRINT("\n create Queues");
    334   queue_ptr->ptr_cmdq = (struct video_msgq*) \
    335                         calloc (sizeof (struct video_msgq),
    336                   queue_ptr->commandq_size);
    337   queue_ptr->ptr_dataq = (struct video_msgq*) \
    338               calloc (sizeof (struct video_msgq),
    339                   queue_ptr->dataq_size
    340                   );
    341 
    342   if ( queue_ptr->ptr_cmdq == NULL ||
    343      queue_ptr->ptr_dataq == NULL
    344     )
    345   {
    346     return -1;
    347   }
    348   DEBUG_PRINT("\n create Threads");
    349   /*Create two threads*/
    350     if ( (pthread_create (&init_decode->videothread_id,NULL,video_thread,
    351             init_decode) < 0) ||
    352          (pthread_create (&init_decode->asyncthread_id,NULL,async_thread,
    353             init_decode) < 0)
    354     )
    355   {
    356     return -1;
    357   }
    358 
    359   return 1;
    360 }
    361 
    362 
    363 
    364 int free_buffer ( enum vdec_buffer buffer_dir,
    365                   struct video_decoder_context *decode_context
    366                  )
    367 {
    368   unsigned int buffercount = 0,i=0;
    369   struct vdec_bufferpayload **ptemp = NULL;
    370 
    371   if (decode_context == NULL)
    372   {
    373     return -1;
    374   }
    375 
    376   if (buffer_dir == VDEC_BUFFER_TYPE_INPUT && decode_context->ptr_inputbuffer)
    377   {
    378       buffercount = decode_context->input_buffer.actualcount;
    379       ptemp = decode_context->ptr_inputbuffer;
    380 
    381     for (i=0;i<buffercount;i++)
    382     {
    383           if (ptemp [i])
    384       {
    385             if (ptemp [i]->pmem_fd != -1)
    386       {
    387         munmap ( ptemp [i]->bufferaddr,ptemp [i]->mmaped_size);
    388         ptemp [i]->bufferaddr = NULL;
    389         close (ptemp [i]->pmem_fd);
    390       }
    391       free (ptemp [i]);
    392       ptemp [i] = NULL;
    393       }
    394     }
    395     free (decode_context->ptr_inputbuffer);
    396     decode_context->ptr_inputbuffer = NULL;
    397   }
    398   else if ( buffer_dir == VDEC_BUFFER_TYPE_OUTPUT )
    399   {
    400     buffercount = decode_context->output_buffer.actualcount;
    401     ptemp = decode_context->ptr_outputbuffer;
    402 
    403         if (decode_context->ptr_respbuffer)
    404     {
    405       for (i=0;i<buffercount;i++)
    406       {
    407         if (decode_context->ptr_respbuffer [i])
    408         {
    409           free (decode_context->ptr_respbuffer[i]);
    410           decode_context->ptr_respbuffer [i] = NULL;
    411         }
    412       }
    413       free (decode_context->ptr_respbuffer);
    414       decode_context->ptr_respbuffer = NULL;
    415     }
    416 
    417     if (ptemp)
    418     {
    419       for (i=0;i<buffercount;i++)
    420       {
    421         if (ptemp [i])
    422         {
    423           if (ptemp [i]->pmem_fd != -1)
    424           {
    425             munmap ( ptemp [i]->bufferaddr,ptemp [i]->mmaped_size);
    426             ptemp [i]->bufferaddr = NULL;
    427             close (ptemp [i]->pmem_fd);
    428           }
    429           free (ptemp [i]);
    430           ptemp [i] = NULL;
    431         }
    432       }
    433       free (ptemp);
    434       decode_context->ptr_outputbuffer = NULL;
    435     }
    436   }
    437 
    438   return 1;
    439 }
    440 
    441 int allocate_buffer ( enum vdec_buffer buffer_dir,
    442                       struct video_decoder_context *decode_context
    443                     )
    444 {
    445   struct vdec_setbuffer_cmd setbuffers;
    446   struct vdec_bufferpayload **ptemp = NULL;
    447   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
    448   unsigned int buffercount = 0,i=0,alignedsize=0;
    449   unsigned int buffersize = 0;
    450 
    451   if ( decode_context == NULL)
    452   {
    453     DEBUG_PRINT ("\nallocate_buffer: context is NULL");
    454     return -1;
    455   }
    456 
    457   if ( buffer_dir == VDEC_BUFFER_TYPE_INPUT )
    458   {
    459         /*Check if buffers are allocated*/
    460     if (decode_context->ptr_inputbuffer != NULL)
    461     {
    462       DEBUG_PRINT ("\nallocate_buffer: decode_context->ptr_inputbuffer is set");
    463       return -1;
    464     }
    465 
    466     buffercount = decode_context->input_buffer.actualcount;
    467     alignedsize = decode_context->input_buffer.alignment;
    468     buffersize = decode_context->input_buffer.buffer_size;
    469     buffersize = (buffersize + alignedsize) & (~alignedsize);
    470   }
    471   else if (buffer_dir == VDEC_BUFFER_TYPE_OUTPUT)
    472   {
    473     /*Check if buffers are allocated*/
    474     if (decode_context->ptr_outputbuffer != NULL)
    475     {
    476       DEBUG_PRINT ("\nallocate_buffer: Double allcoate output");
    477       return -1;
    478     }
    479 
    480     buffercount = decode_context->output_buffer.actualcount;
    481     alignedsize = decode_context->output_buffer.alignment;
    482     buffersize = decode_context->output_buffer.buffer_size;
    483     buffersize = (buffersize + alignedsize) & (~alignedsize);
    484 
    485     decode_context->ptr_respbuffer = (struct vdec_output_frameinfo  **)\
    486     calloc (sizeof (struct vdec_output_frameinfo *),buffercount);
    487 
    488     if (decode_context->ptr_respbuffer == NULL)
    489     {
    490       DEBUG_PRINT ("\n Allocate failure ptr_respbuffer");
    491     }
    492 
    493     for (i=0; i< buffercount; i++)
    494     {
    495       decode_context->ptr_respbuffer [i] = (struct vdec_output_frameinfo *)\
    496       calloc (sizeof (struct vdec_output_frameinfo),buffercount);
    497       if (decode_context->ptr_respbuffer [i] == NULL)
    498       {
    499         DEBUG_PRINT ("\nfailed to allocate vdec_output_frameinfo");
    500         return -1;
    501       }
    502     }
    503   }
    504   else
    505   {
    506     DEBUG_PRINT ("\nallocate_buffer: Wrong buffer directions");
    507     return -1;
    508   }
    509 
    510   ptemp = (struct vdec_bufferpayload **)\
    511   calloc (sizeof (struct vdec_bufferpayload *),buffercount);
    512 
    513   if (ptemp == NULL)
    514   {
    515     DEBUG_PRINT ("\nallocate_buffer: vdec_bufferpayload failure");
    516     return -1;
    517   }
    518 
    519 
    520   if (buffer_dir == VDEC_BUFFER_TYPE_OUTPUT)
    521   {
    522     DEBUG_PRINT ("\nallocate_buffer: OUT");
    523     decode_context->ptr_outputbuffer = ptemp;
    524   }
    525   else
    526   {
    527     DEBUG_PRINT ("\nallocate_buffer: IN");
    528     decode_context->ptr_inputbuffer = ptemp;
    529   }
    530 
    531   /*Allocate buffer headers*/
    532   for (i=0; i< buffercount; i++)
    533   {
    534     ptemp [i] = (struct vdec_bufferpayload*)\
    535     calloc (sizeof (struct vdec_bufferpayload),1);
    536 
    537     if (ptemp [i] == NULL)
    538     {
    539       DEBUG_PRINT ("\nallocate_buffer: ptemp [i] calloc failure");
    540       return -1;
    541     }
    542 
    543     if (buffer_dir == VDEC_BUFFER_TYPE_OUTPUT)
    544     {
    545          decode_context->ptr_respbuffer [i]->client_data = \
    546          (void *) ptemp [i];
    547     }
    548     ptemp [i]->pmem_fd = -1;
    549 
    550   }
    551 
    552   for (i=0; i< buffercount; i++)
    553   {
    554     ptemp [i]->pmem_fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
    555 
    556     if (ptemp [i]->pmem_fd < 0)
    557     {
    558       DEBUG_PRINT ("\nallocate_buffer: open pmem failed");
    559       return -1;
    560     }
    561 
    562     ptemp [i]->bufferaddr = mmap(NULL,clp2(buffersize),PROT_READ|PROT_WRITE,
    563                                  MAP_SHARED,ptemp [i]->pmem_fd,0);
    564     DEBUG_PRINT ("\n pmem fd = %d virt addr = %p",ptemp [i]->pmem_fd,\
    565                   ptemp [i]->bufferaddr);
    566     if (ptemp [i]->bufferaddr == MAP_FAILED)
    567     {
    568       ptemp [i]->bufferaddr = NULL;
    569       DEBUG_PRINT ("\nallocate_buffer: MMAP failed");
    570       return -1;
    571     }
    572     ptemp [i]->buffer_len = buffersize;
    573     ptemp [i]->mmaped_size = clp2 (buffersize);
    574 
    575     setbuffers.buffer_type = buffer_dir;
    576     memcpy (&setbuffers.buffer,ptemp [i],sizeof (struct vdec_bufferpayload));
    577 
    578     ioctl_msg.inputparam  = &setbuffers;
    579     ioctl_msg.outputparam = NULL;
    580 
    581     if (ioctl (decode_context->video_driver_fd,VDEC_IOCTL_SET_BUFFER,
    582          &ioctl_msg) < 0)
    583     {
    584       DEBUG_PRINT ("\nallocate_buffer: Set Buffer IOCTL failed");
    585       return -1;
    586     }
    587 
    588   }
    589   DEBUG_PRINT ("\nallocate_buffer: Success");
    590   return 1;
    591 }
    592 
    593 
    594 
    595 int start_decoding (struct video_decoder_context *decode_context)
    596 {
    597   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
    598   struct vdec_input_frameinfo frameinfo;
    599   struct vdec_fillbuffer_cmd fillbuffer;
    600   unsigned int i = 0;
    601   unsigned int data_len =0;
    602 
    603   memset ((unsigned char*)&frameinfo,0,sizeof (struct vdec_input_frameinfo));
    604   memset ((unsigned char*)&fillbuffer,0,sizeof (struct vdec_fillbuffer_cmd));
    605 
    606   if (decode_context == NULL)
    607   {
    608     return -1;
    609   }
    610 
    611   if (ioctl (decode_context->video_driver_fd,VDEC_IOCTL_CMD_START,
    612          NULL) < 0)
    613   {
    614     DEBUG_PRINT("\n Start failed");
    615     return -1;
    616   }
    617 
    618   DEBUG_PRINT("\n Start Issued successfully waiting for Start Done");
    619   /*Wait for Start command response*/
    620     sem_wait (&decode_context->sem_synchronize);
    621 
    622   /*Push output Buffers*/
    623   i = 0;
    624   while (i < decode_context->output_buffer.mincount)
    625   {
    626     fillbuffer.buffer.buffer_len =
    627                                decode_context->ptr_outputbuffer [i]->buffer_len;
    628     fillbuffer.buffer.bufferaddr =
    629                                decode_context->ptr_outputbuffer [i]->bufferaddr;
    630     fillbuffer.buffer.offset =
    631                                decode_context->ptr_outputbuffer [i]->offset;
    632     fillbuffer.buffer.pmem_fd =
    633                                decode_context->ptr_outputbuffer [i]->pmem_fd;
    634     fillbuffer.client_data = (void *)decode_context->ptr_respbuffer [i];
    635     DEBUG_PRINT ("\n Client Data on output = %p",fillbuffer.client_data);
    636     ioctl_msg.inputparam = &fillbuffer;
    637     ioctl_msg.outputparam = NULL;
    638 
    639     if (ioctl (decode_context->video_driver_fd,
    640            VDEC_IOCTL_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0)
    641     {
    642       DEBUG_PRINT("\n Decoder frame failed");
    643       return -1;
    644     }
    645     i++;
    646   }
    647 
    648 
    649   /*push input buffers*/
    650   i = 0;
    651   while (i < decode_context->input_buffer.mincount)
    652   {
    653     DEBUG_PRINT("\n Read  Frame from File");
    654     data_len = read_frame ( decode_context->ptr_inputbuffer [i]->bufferaddr,
    655                        decode_context->ptr_inputbuffer [i]->buffer_len,
    656              decode_context->inputBufferFile);
    657     if (data_len == 0)
    658     {
    659       DEBUG_PRINT("\n Length is zero error");
    660       return -1;
    661     }
    662     DEBUG_PRINT("\n Read  Frame from File szie = %u",data_len);
    663     frameinfo.bufferaddr =
    664     decode_context->ptr_inputbuffer [i]->bufferaddr;
    665     frameinfo.offset = 0;
    666     frameinfo.pmem_fd = decode_context->ptr_inputbuffer [i]->pmem_fd;
    667     frameinfo.pmem_offset = decode_context->ptr_inputbuffer [i]->offset;
    668     frameinfo.datalen = data_len;
    669     frameinfo.client_data = (struct vdec_bufferpayload *)\
    670                            decode_context->ptr_inputbuffer [i];
    671     /*TODO: Time stamp needs to be updated*/
    672     ioctl_msg.inputparam = &frameinfo;
    673     ioctl_msg.outputparam = NULL;
    674 
    675     if (ioctl (decode_context->video_driver_fd,VDEC_IOCTL_DECODE_FRAME,
    676          &ioctl_msg) < 0)
    677     {
    678       DEBUG_PRINT("\n Decoder frame failed");
    679       return -1;
    680     }
    681     total_frames++;
    682     i++;
    683   }
    684   DEBUG_PRINT ("\n Wait for EOS");
    685   /*Wait for EOS or Error condition*/
    686   sem_wait (&decode_context->sem_synchronize);
    687   DEBUG_PRINT ("\n Reached EOS");
    688 
    689   return 1;
    690 }
    691 
    692 int stop_decoding  (struct video_decoder_context *decode_context)
    693 {
    694   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
    695   enum vdec_bufferflush flush_dir = VDEC_FLUSH_TYPE_INPUT;
    696 
    697   if (decode_context == NULL)
    698   {
    699     return -1;
    700   }
    701 
    702   ioctl_msg.inputparam = &flush_dir;
    703   ioctl_msg.outputparam = NULL;
    704 
    705   if (ioctl(decode_context->video_driver_fd,VDEC_IOCTL_CMD_FLUSH,
    706          &ioctl_msg) < 0)
    707   {
    708     DEBUG_PRINT("\n Flush input failed");
    709   }
    710   else
    711   {
    712        sem_wait (&decode_context->sem_synchronize);
    713   }
    714 
    715   flush_dir = VDEC_FLUSH_TYPE_OUTPUT;
    716   ioctl_msg.inputparam = &flush_dir;
    717   ioctl_msg.outputparam = NULL;
    718 
    719   if (ioctl(decode_context->video_driver_fd,VDEC_IOCTL_CMD_FLUSH,
    720          &ioctl_msg) < 0)
    721   {
    722     DEBUG_PRINT("\n Flush output failed");
    723   }
    724   else
    725   {
    726      sem_wait (&decode_context->sem_synchronize);
    727   }
    728 
    729   DEBUG_PRINT("\n Stop VDEC_IOCTL_CMD_STOP");
    730   if (ioctl(decode_context->video_driver_fd,VDEC_IOCTL_CMD_STOP,
    731          NULL) < 0)
    732   {
    733     DEBUG_PRINT("\n Stop failed");
    734   }
    735   else
    736   {
    737      sem_wait (&decode_context->sem_synchronize);
    738   }
    739   return 1;
    740 }
    741 
    742 int deinit_decoder (struct video_decoder_context *init_decode)
    743 {
    744   if (init_decode == NULL)
    745   {
    746     return -1;
    747   }
    748 
    749   /*Close the driver*/
    750   if (init_decode->video_driver_fd != -1)
    751   {
    752     close (init_decode->video_driver_fd);
    753   }
    754 
    755   if (init_decode->queue_context.ptr_cmdq)
    756   {
    757     free (init_decode->queue_context.ptr_cmdq);
    758     init_decode->queue_context.ptr_cmdq = NULL;
    759   }
    760 
    761   if (init_decode->queue_context.ptr_dataq)
    762   {
    763     free (init_decode->queue_context.ptr_dataq);
    764     init_decode->queue_context.ptr_dataq = NULL;
    765   }
    766 
    767   sem_destroy (&init_decode->queue_context.sem_message);
    768   sem_destroy (&init_decode->sem_synchronize);
    769 
    770   pthread_mutex_destroy(&init_decode->queue_context.mutex);
    771   pthread_mutex_destroy (&read_lock);
    772 
    773   return 1;
    774 }
    775 
    776 static void* video_thread (void *context)
    777 {
    778    struct video_decoder_context *decode_context = NULL;
    779    struct video_msgq *queueitem = NULL;
    780    struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
    781    struct vdec_input_frameinfo frameinfo;
    782    struct vdec_fillbuffer_cmd fillbuffer;
    783    struct vdec_output_frameinfo *outputbuffer = NULL;
    784    struct vdec_bufferpayload *tempbuffer = NULL;
    785    unsigned int data_len =0;
    786 
    787 
    788    if (context == NULL)
    789    {
    790      DEBUG_PRINT("\n video thread recieved NULL context");
    791      return NULL;
    792    }
    793    decode_context = (struct video_decoder_context *) context;
    794 
    795    /* Thread function which will accept commands from async thread
    796     * or main thread
    797    */
    798    while (1)
    799    {
    800       queueitem = queue_get_cmd (&decode_context ->queue_context);
    801       if (queueitem != NULL)
    802       {
    803         switch (queueitem->cmd)
    804         {
    805         case VDEC_MSG_EVT_HW_ERROR:
    806           DEBUG_PRINT("\n FATAL ERROR ");
    807           break;
    808         case VDEC_MSG_RESP_INPUT_FLUSHED:
    809           DEBUG_PRINT("\n Input Buffer Flushed");
    810           break;
    811         case VDEC_MSG_RESP_OUTPUT_FLUSHED:
    812           DEBUG_PRINT("\n Output buffer Flushed");
    813           break;
    814         case VDEC_MSG_RESP_START_DONE:
    815           DEBUG_PRINT("\n recived start done command");
    816             sem_post (&decode_context->sem_synchronize);
    817           break;
    818 
    819         case VDEC_MSG_RESP_STOP_DONE:
    820           DEBUG_PRINT("\n recieved stop done");
    821           sem_post (&decode_context->sem_synchronize);
    822           break;
    823 
    824         case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
    825 
    826           tempbuffer = (struct vdec_bufferpayload *)queueitem->clientdata;
    827           if (tempbuffer == NULL)
    828           {
    829             DEBUG_PRINT("\n FATAL ERROR input buffer address is bad");
    830             sem_post (&decode_context->sem_synchronize);
    831             break;
    832           }
    833           data_len = read_frame ( tempbuffer->bufferaddr,
    834                         tempbuffer->buffer_len,
    835                         decode_context->inputBufferFile
    836                      );
    837 
    838           if (data_len == 0)
    839           {
    840             DEBUG_PRINT ("\n End of stream reached");
    841             sem_post (&decode_context->sem_synchronize);
    842             break;
    843           }
    844 
    845           frameinfo.bufferaddr = tempbuffer->bufferaddr;
    846           frameinfo.offset = 0;
    847           frameinfo.pmem_fd = tempbuffer->pmem_fd;
    848           frameinfo.pmem_offset = tempbuffer->offset;
    849           frameinfo.datalen = data_len;
    850           frameinfo.client_data = (struct vdec_bufferpayload *)\
    851                        tempbuffer;
    852           /*TODO: Time stamp needs to be updated*/
    853           ioctl_msg.inputparam = &frameinfo;
    854           ioctl_msg.outputparam = NULL;
    855           total_frames++;
    856           if (ioctl(decode_context->video_driver_fd,VDEC_IOCTL_DECODE_FRAME,
    857                &ioctl_msg) < 0)
    858           {
    859             DEBUG_PRINT("\n Decoder frame failed");
    860             sem_post (&decode_context->sem_synchronize);
    861           }
    862           DEBUG_PRINT("\n Input buffer done send next buffer current value = %d",\
    863                       total_frames);
    864           break;
    865 
    866         case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
    867 
    868          outputbuffer = (struct vdec_output_frameinfo *)\
    869                               queueitem->clientdata;
    870          DEBUG_PRINT("\n Value of client Data in VT %p",queueitem->clientdata);
    871          if (outputbuffer == NULL || outputbuffer->bufferaddr == NULL ||
    872                    outputbuffer->client_data == NULL
    873            )
    874          {
    875            DEBUG_PRINT("\n FATAL ERROR output buffer is bad");
    876            DEBUG_PRINT("\nValues outputbuffer = %p",outputbuffer);
    877            DEBUG_PRINT("\nValues outputbuffer->bufferaddr = %p",\
    878                        outputbuffer->bufferaddr);
    879            DEBUG_PRINT("\nValues outputbuffer->client_data = %p",\
    880                        outputbuffer->client_data);
    881            sem_post (&decode_context->sem_synchronize);
    882            break;
    883          }
    884 
    885 
    886          if (outputbuffer->len == 0)
    887          {
    888            DEBUG_PRINT("\n Filled Length is zero Close decoding");
    889            sem_post (&decode_context->sem_synchronize);
    890            break;
    891          }
    892 
    893          if (decode_context->outputBufferFile != NULL)
    894          {
    895            fwrite (outputbuffer->bufferaddr,1,outputbuffer->len,
    896                 decode_context->outputBufferFile);
    897          }
    898 
    899          tempbuffer = (struct vdec_bufferpayload *)\
    900                      outputbuffer->client_data;
    901 
    902          DEBUG_PRINT("\n recieved output buffer consume outbuffer");
    903          DEBUG_PRINT("\nValues outputbuffer->bufferaddr = %p",\
    904                      outputbuffer->bufferaddr);
    905          DEBUG_PRINT ("\n Vir address of allocated buffer %p",\
    906                       tempbuffer->bufferaddr);
    907          fillbuffer.buffer.buffer_len = tempbuffer->buffer_len;
    908          fillbuffer.buffer.bufferaddr = tempbuffer->bufferaddr;
    909          fillbuffer.buffer.offset = tempbuffer->offset;
    910          fillbuffer.buffer.pmem_fd = tempbuffer->pmem_fd;
    911          fillbuffer.client_data = (void *)outputbuffer;
    912 
    913          ioctl_msg.inputparam = &fillbuffer;
    914          ioctl_msg.outputparam = NULL;
    915 
    916          if (ioctl (decode_context->video_driver_fd,
    917               VDEC_IOCTL_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0)
    918          {
    919            DEBUG_PRINT("\n Decoder frame failed");
    920            return NULL;
    921          }
    922 
    923          break;
    924 
    925         case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
    926             DEBUG_PRINT("\n Flush input complete");
    927           sem_post (&decode_context->sem_synchronize);
    928           break;
    929 
    930         case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
    931           DEBUG_PRINT("\n Flush output complete");
    932                 sem_post (&decode_context->sem_synchronize);
    933           break;
    934          }
    935       }
    936       else
    937       {
    938         DEBUG_PRINT("\n Error condition recieved NULL from Queue");
    939       }
    940 
    941       if (queueitem->cmd == VDEC_MSG_RESP_STOP_DONE)
    942       {
    943         DEBUG_PRINT("\n Playback has ended thread will exit");
    944         return NULL;
    945       }
    946    }
    947 }
    948 
    949 static void* async_thread (void *context)
    950 {
    951   struct video_decoder_context *decode_context = NULL;
    952   struct vdec_output_frameinfo *outputframe = NULL;
    953   struct video_msgq queueitem ;
    954   struct vdec_msginfo vdec_msg;
    955   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
    956   int result = -1;
    957 
    958   if (context == NULL)
    959   {
    960     DEBUG_PRINT("\n aynsc thread recieved NULL context");
    961     return NULL;
    962   }
    963   decode_context = (struct video_decoder_context *) context;
    964   DEBUG_PRINT("\n Entering the async thread");
    965 
    966   while (1)
    967   {
    968     ioctl_msg.inputparam = NULL;
    969 
    970     ioctl_msg.outputparam = (void*)&vdec_msg;
    971     DEBUG_PRINT ("\n Sizeof vdec_msginfo = %d ",sizeof (vdec_msg));
    972     DEBUG_PRINT("\n Address of Vdec msg in async thread %p",\
    973                 ioctl_msg.outputparam);
    974     if (ioctl (decode_context->video_driver_fd,VDEC_IOCTL_GET_NEXT_MSG,\
    975          (void*)&ioctl_msg) < 0)
    976     {
    977       DEBUG_PRINT("\n Error in ioctl read next msg");
    978     }
    979     else
    980     {
    981       switch (vdec_msg.msgcode)
    982       {
    983       case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
    984       case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
    985       case VDEC_MSG_RESP_START_DONE:
    986       case VDEC_MSG_RESP_STOP_DONE:
    987       case VDEC_MSG_EVT_HW_ERROR:
    988         DEBUG_PRINT("\nioctl read next msg");
    989         queueitem.cmd = vdec_msg.msgcode;
    990         queueitem.status = vdec_msg.status_code;
    991         queueitem.clientdata = NULL;
    992         break;
    993 
    994       case VDEC_MSG_RESP_INPUT_FLUSHED:
    995       case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
    996 
    997         queueitem.cmd = vdec_msg.msgcode;
    998         queueitem.status = vdec_msg.status_code;
    999         queueitem.clientdata = (void *)\
   1000             vdec_msg.msgdata.input_frame_clientdata;
   1001         break;
   1002 
   1003       case VDEC_MSG_RESP_OUTPUT_FLUSHED:
   1004       case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
   1005         queueitem.cmd = vdec_msg.msgcode;
   1006         queueitem.status = vdec_msg.status_code;
   1007         outputframe = (struct vdec_output_frameinfo *)\
   1008         vdec_msg.msgdata.output_frame.client_data;
   1009         DEBUG_PRINT ("\n Client Data value in %p", \
   1010                      vdec_msg.msgdata.output_frame.client_data);
   1011         outputframe->bufferaddr = vdec_msg.msgdata.output_frame.bufferaddr;
   1012         outputframe->framesize.bottom = \
   1013         vdec_msg.msgdata.output_frame.framesize.bottom;
   1014         outputframe->framesize.left = \
   1015         vdec_msg.msgdata.output_frame.framesize.left;
   1016         outputframe->framesize.right = \
   1017         vdec_msg.msgdata.output_frame.framesize.right;
   1018         outputframe->framesize.top = \
   1019         vdec_msg.msgdata.output_frame.framesize.top;
   1020         outputframe->framesize = vdec_msg.msgdata.output_frame.framesize;
   1021         outputframe->len = vdec_msg.msgdata.output_frame.len;
   1022         outputframe->time_stamp = vdec_msg.msgdata.output_frame.time_stamp;
   1023         queueitem.clientdata = (void *)outputframe;
   1024         DEBUG_PRINT ("\n Client Data value Copy %p",queueitem.clientdata);
   1025        break;
   1026 
   1027       default:
   1028         DEBUG_PRINT("\nIn Default of get next message %d",vdec_msg.msgcode);
   1029         queueitem.cmd = vdec_msg.msgcode;
   1030         queueitem.status = vdec_msg.status_code;
   1031         queueitem.clientdata = NULL;
   1032         break;
   1033       }
   1034       result = queue_post_cmdq (&decode_context->queue_context,&queueitem);
   1035       while (result == 0)
   1036       {
   1037          result = queue_post_cmdq (&decode_context->queue_context,
   1038                  &queueitem);
   1039       }
   1040 
   1041       if (result == -1)
   1042       {
   1043         DEBUG_PRINT("\n FATAL ERROR WITH Queue");
   1044       }
   1045     }
   1046     if (vdec_msg.msgcode == VDEC_MSG_RESP_STOP_DONE)
   1047     {
   1048       /*Thread can exit at this point*/
   1049       return NULL;
   1050     }
   1051   }
   1052 }
   1053 
   1054 
   1055 static unsigned int read_frame (unsigned char *dataptr, unsigned int length,
   1056                                 FILE * inputBufferFile)
   1057 {
   1058 
   1059   unsigned int readOffset = 0;
   1060   int bytes_read = 0;
   1061   unsigned int code = 0;
   1062   int found = 0;
   1063 
   1064   DEBUG_PRINT ("\n Inside the readframe");
   1065 
   1066   if (dataptr == NULL && length == 0)
   1067   {
   1068     DEBUG_PRINT ("\n dataptr = %p length = %u",dataptr,length);
   1069     return 0;
   1070   }
   1071 
   1072   if (!Code_type)
   1073   {
   1074     /* Start of Critical Section*/
   1075     pthread_mutex_lock(&read_lock);
   1076     do
   1077     {
   1078       //Start codes are always byte aligned.
   1079       bytes_read = fread(&dataptr[readOffset],1, 1,inputBufferFile);
   1080       if( !bytes_read)
   1081       {
   1082         DEBUG_PRINT("\n Bytes read Zero \n");
   1083         break;
   1084       }
   1085       code <<= 8;
   1086       code |= (0x000000FF & dataptr[readOffset]);
   1087       //VOP start code comparision
   1088       if (readOffset>3)
   1089       {
   1090         if(!header_code )
   1091         {
   1092           if( VOP_START_CODE == code)
   1093           {
   1094           DEBUG_PRINT ("\n Found VOP Code");
   1095           header_code = VOP_START_CODE;
   1096           }
   1097           else if ( (0xFFFFFC00 & code) == SHORT_HEADER_START_CODE )
   1098           {
   1099           header_code = SHORT_HEADER_START_CODE;
   1100           }
   1101         }
   1102         if ((header_code == VOP_START_CODE) && (code == VOP_START_CODE))
   1103         {
   1104           //Seek backwards by 4
   1105           fseek(inputBufferFile, -4, SEEK_CUR);
   1106           readOffset-=4;
   1107           found = 1;
   1108           break;
   1109 
   1110         }
   1111         else if (( header_code == SHORT_HEADER_START_CODE ) &&
   1112         ( SHORT_HEADER_START_CODE == (code & 0xFFFFFC00)))
   1113         {
   1114           //Seek backwards by 4
   1115           fseek(inputBufferFile, -4, SEEK_CUR);
   1116           readOffset-=4;
   1117           found = 1;
   1118           break;
   1119         }
   1120       }
   1121       readOffset++;
   1122     }while (readOffset < length);
   1123     pthread_mutex_unlock(&read_lock);
   1124     /* End of Critical Section*/
   1125     if (found == 1)
   1126     {
   1127       //DEBUG_PRINT ("Found a Frame");
   1128       return (readOffset+1);
   1129     }
   1130     else
   1131     {
   1132       //DEBUG_PRINT ("No Frames detected");
   1133       return 0;
   1134     }
   1135   }
   1136   else
   1137   {
   1138 
   1139     readOffset = Read_Buffer_From_DAT_File(dataptr,length,inputBufferFile);
   1140     if (total_frames == 0)
   1141     {
   1142       bytes_read = Read_Buffer_From_DAT_File(&dataptr[readOffset],
   1143                                              (length-readOffset),
   1144                                              inputBufferFile);
   1145       readOffset += bytes_read;
   1146     }
   1147     return (readOffset);
   1148   }
   1149 
   1150 }
   1151 
   1152 static int Read_Buffer_From_DAT_File(unsigned char *dataptr, unsigned int length,
   1153                                      FILE * inputBufferFile)
   1154 {
   1155 
   1156 
   1157   long frameSize=0;
   1158   char temp_buffer[10];
   1159   char temp_byte;
   1160   int bytes_read=0;
   1161   int i=0;
   1162   unsigned char *read_buffer=NULL;
   1163   char c = '1'; //initialize to anything except '\0'(0)
   1164   char inputFrameSize[10];
   1165   int count =0; int cnt =0;
   1166   memset(temp_buffer, 0, sizeof(temp_buffer));
   1167 
   1168   while (cnt < 10)
   1169   /* Check the input file format, may result in infinite loop */
   1170   {
   1171       count  = fread(&inputFrameSize[cnt],1,1,inputBufferFile);
   1172       if(inputFrameSize[cnt] == '\0' )
   1173         break;
   1174       cnt++;
   1175   }
   1176   inputFrameSize[cnt]='\0';
   1177   frameSize = atoi(inputFrameSize);
   1178   //length = 0;
   1179   DEBUG_PRINT ("\n Frame Size is %ld",frameSize);
   1180 
   1181   /* get the frame length */
   1182   fseek(inputBufferFile, -1, SEEK_CUR);
   1183   bytes_read = fread(dataptr, 1, frameSize,  inputBufferFile);
   1184 
   1185   if(bytes_read == 0 || bytes_read < frameSize ) {
   1186       return 0;
   1187   }
   1188   return bytes_read;
   1189 }
   1190