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