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