1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6     * Redistributions of source code must retain the above copyright
7       notice, this list of conditions and the following disclaimer.
8     * Redistributions in binary form must reproduce the above copyright
9       notice, this list of conditions and the following disclaimer in the
10       documentation and/or other materials provided with the distribution.
11     * Neither the name of Code Aurora nor
12       the names of its contributors may be used to endorse or promote
13       products derived from this software without specific prior written
14       permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 --------------------------------------------------------------------------*/
28 #include "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                                 );
clp2(unsigned x)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 
main(int argc,char ** argv)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   {
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 
init_encoder(struct video_encoder_context * init_decode)225 int 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 
free_buffer(unsigned int buffer_dir,struct video_encoder_context * encoder_context)422 int 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 
allocate_buffer(unsigned int buffer_dir,struct video_encoder_context * encoder_context)485 int 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 
start_encoding(struct video_encoder_context * encoder_context)622 int 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 
stop_encoding(struct video_encoder_context * encoder_context)720 int 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 
deinit_encoder(struct video_encoder_context * init_decode)769 int 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 
video_thread(void * context)803 static 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 
async_thread(void * context)950 static 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 
read_frame(unsigned char * dataptr,unsigned int length,FILE * inputBufferFile)1042 static 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