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