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 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 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 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 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 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 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 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 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 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 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 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 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