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