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