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