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