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 "video_encoder_test.h" 29 30 #define DEBUG_PRINT printf 31 /************************************************************************/ 32 /* #DEFINES */ 33 /************************************************************************/ 34 35 #define VOP_START_CODE 0x000001B6 36 #define SHORT_HEADER_START_CODE 0x00008000 37 #define H264_START_CODE 0x00000001 38 39 /************************************************************************/ 40 /* STATIC VARIABLES */ 41 /************************************************************************/ 42 43 static int Code_type; 44 static int total_frames = 0; 45 static unsigned int header_code = 0; 46 static pthread_mutex_t read_lock; 47 48 static unsigned int read_frame ( unsigned char *dataptr,unsigned int length, 49 FILE * inputBufferFile 50 ); 51 static unsigned clp2(unsigned x) 52 { 53 x = x - 1; 54 x = x | (x >> 1); 55 x = x | (x >> 2); 56 x = x | (x >> 4); 57 x = x | (x >> 8); 58 x = x | (x >>16); 59 return x + 1; 60 } 61 62 63 static void* video_thread (void *); 64 static void* async_thread (void *); 65 66 67 68 int main (int argc, char **argv) 69 { 70 struct video_encoder_context *encoder_context = NULL; 71 char *file_name = NULL; 72 FILE *file_ptr = NULL; 73 int temp1 =0,temp2 =0; 74 int error = 1; 75 unsigned int i = 0; 76 77 file_name = argv [1]; 78 file_ptr = fopen (file_name,"rb"); 79 80 if (file_ptr == NULL) 81 { 82 DEBUG_PRINT("\n File is not located "); 83 return -1; 84 } 85 86 87 encoder_context = (struct video_encoder_context *) \ 88 calloc (sizeof (struct video_encoder_context),1); 89 90 encoder_context->outputBufferFile = NULL; 91 encoder_context->inputBufferFile = NULL; 92 encoder_context->video_driver_fd = -1; 93 94 if (encoder_context == NULL) 95 { 96 return -1; 97 } 98 99 encoder_context->inputBufferFile = file_ptr; 100 encoder_context->input_width = 176; 101 encoder_context->input_height = 144; 102 encoder_context->codectype = VEN_CODEC_MPEG4; 103 encoder_context->fps_num = 60; 104 encoder_context->fps_den = 2; 105 encoder_context->inputformat = VEN_INPUTFMT_NV12; 106 encoder_context->targetbitrate = 128000; 107 108 file_ptr = fopen ("/data/output.m4v","wb"); 109 if (file_ptr == NULL) 110 { 111 DEBUG_PRINT("\n File can't be created"); 112 return -1; 113 } 114 encoder_context->outputBufferFile = file_ptr; 115 116 switch (atoi(argv[2])) 117 { 118 case 0: 119 DEBUG_PRINT("\n MPEG4 codec selected"); 120 encoder_context->codectype = VEN_CODEC_MPEG4; 121 Code_type = 0; 122 break; 123 case 1: 124 DEBUG_PRINT("\n H.263"); 125 encoder_context->codectype = VEN_CODEC_H263; 126 Code_type = 0; 127 break; 128 case 2: 129 DEBUG_PRINT("\n H.264"); 130 encoder_context->codectype = VEN_CODEC_H264; 131 Code_type = 1; 132 break; 133 default: 134 DEBUG_PRINT("\n Wrong codec type"); 135 error = -1; 136 break; 137 } 138 139 if (error != -1) 140 { 141 temp1 = atoi(argv[3]); 142 temp2 = atoi(argv[4]); 143 144 if (((temp1%16) != 0) || ((temp2%16) != 0)) 145 { 146 error = -1; 147 } 148 else 149 { 150 encoder_context->input_width = temp1; 151 encoder_context->input_height = temp2; 152 } 153 } 154 155 switch (atoi(argv[5])) 156 { 157 case 0: 158 DEBUG_PRINT("\n No Sink"); 159 encoder_context->outputBufferFile = NULL; 160 break; 161 } 162 163 if (error != -1) 164 { 165 encoder_context->targetbitrate = atoi (argv[6]); 166 } 167 168 if ( error != -1 && (init_encoder (encoder_context) == -1 )) 169 { 170 DEBUG_PRINT("\n Init decoder fails "); 171 error = -1; 172 } 173 DEBUG_PRINT("\n Decoder open successfull"); 174 175 176 /*Allocate input and output buffers*/ 177 if (error != -1 && (allocate_buffer (0,encoder_context)== -1)) 178 { 179 DEBUG_PRINT("\n Error in input Buffer allocation"); 180 error = -1; 181 } 182 183 if (error != -1 && (allocate_buffer (1,encoder_context)== -1)) 184 { 185 DEBUG_PRINT("\n Error in output Buffer allocation"); 186 error = -1; 187 } 188 189 190 if (error != -1 && (start_encoding (encoder_context) == -1)) 191 { 192 DEBUG_PRINT("\n Error in start decoding call"); 193 error = -1; 194 } 195 196 if (error != -1 && (stop_encoding (encoder_context) == -1)) 197 { 198 DEBUG_PRINT("\n Error in stop decoding call"); 199 error = -1; 200 } 201 202 DEBUG_PRINT("\n De-init the decoder"); 203 if ((deinit_encoder (encoder_context) == -1)) 204 { 205 error = -1; 206 } 207 208 209 (void)free_buffer (INPUT_BUFFER,encoder_context); 210 (void)free_buffer (OUTPUT_BUFFER,encoder_context); 211 212 if (encoder_context->inputBufferFile != NULL) 213 { 214 fclose (encoder_context->inputBufferFile); 215 } 216 if (encoder_context->outputBufferFile != NULL) 217 { 218 fclose (encoder_context->outputBufferFile); 219 } 220 DEBUG_PRINT ("\n Total Number of frames decoded %d",total_frames); 221 DEBUG_PRINT("\n closing the driver"); 222 free (encoder_context); 223 224 return error; 225 } 226 227 int init_encoder ( struct video_encoder_context *init_decode ) 228 { 229 struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; 230 struct venc_basecfg basecfg; 231 struct video_queue_context *queue_ptr = NULL; 232 struct venc_ratectrlcfg ratecrl; 233 pthread_mutexattr_t init_values; 234 struct venc_profile profile; 235 struct ven_profilelevel profilelevel; 236 237 DEBUG_PRINT("\n Before calling the open"); 238 239 init_decode->video_driver_fd = open ("/dev/msm_vidc_enc", \ 240 O_RDWR | O_NONBLOCK); 241 242 243 244 if (init_decode->video_driver_fd < 0) 245 { 246 DEBUG_PRINT("\n Open failed"); 247 return -1; 248 } 249 250 basecfg.codectype = init_decode->codectype; 251 basecfg.dvs_height = 0; 252 basecfg.dvs_width = 0; 253 basecfg.fps_den = init_decode->fps_den; 254 basecfg.fps_num = init_decode->fps_num; 255 basecfg.input_height = init_decode->input_height; 256 basecfg.input_width = init_decode->input_width; 257 basecfg.inputformat = init_decode->inputformat; 258 basecfg.targetbitrate = init_decode->targetbitrate; 259 260 /*Initialize Decoder with codec type and resolution*/ 261 ioctl_msg.inputparam = &basecfg; 262 ioctl_msg.outputparam = NULL; 263 264 if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_BASE_CFG, 265 (void*)&ioctl_msg) < 0) 266 { 267 DEBUG_PRINT("\n Set base config type failed"); 268 return -1; 269 } 270 271 /*Initialize Decoder with codec type and resolution*/ 272 DEBUG_PRINT ("\n Switch off rate control"); 273 ioctl_msg.inputparam = &ratecrl; 274 ioctl_msg.outputparam = NULL; 275 ratecrl.rcmode = VEN_RC_OFF; 276 if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_RATE_CTRL_CFG, 277 (void*)&ioctl_msg) < 0) 278 { 279 DEBUG_PRINT("\n Set rate control failed"); 280 return -1; 281 } 282 283 if (basecfg.codectype == VEN_CODEC_H264) 284 { 285 DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High"); 286 ioctl_msg.inputparam = &profile; 287 ioctl_msg.outputparam = NULL; 288 profile.profile = VEN_PROFILE_H264_BASELINE; 289 if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_CODEC_PROFILE, 290 (void*)&ioctl_msg) < 0) 291 { 292 DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed"); 293 return -1; 294 } 295 296 DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High"); 297 ioctl_msg.inputparam = &profilelevel; 298 ioctl_msg.outputparam = NULL; 299 profilelevel.level = VEN_LEVEL_H264_1p1; 300 if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_PROFILE_LEVEL, 301 (void*)&ioctl_msg) < 0) 302 { 303 DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed"); 304 return -1; 305 } 306 307 if (basecfg.input_width > 720) 308 { 309 DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High"); 310 ioctl_msg.inputparam = &profile; 311 ioctl_msg.outputparam = NULL; 312 profile.profile = VEN_PROFILE_H264_HIGH; 313 if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_CODEC_PROFILE, 314 (void*)&ioctl_msg) < 0) 315 { 316 DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed"); 317 return -1; 318 } 319 320 DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High"); 321 ioctl_msg.inputparam = &profilelevel; 322 ioctl_msg.outputparam = NULL; 323 profilelevel.level = VEN_LEVEL_H264_3p1; 324 if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_PROFILE_LEVEL, 325 (void*)&ioctl_msg) < 0) 326 { 327 DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed"); 328 return -1; 329 } 330 } 331 } 332 333 DEBUG_PRINT("\n Query Input bufffer requirements"); 334 /*Get the Buffer requirements for input and output ports*/ 335 336 337 338 ioctl_msg.inputparam = NULL; 339 ioctl_msg.outputparam = &init_decode->input_buffer; 340 341 if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ, 342 (void*)&ioctl_msg) < 0) 343 { 344 DEBUG_PRINT("\n Requesting for input buffer requirements failed"); 345 return -1; 346 } 347 348 DEBUG_PRINT("\n input Size=%d min count =%d actual count = %d", \ 349 (int)init_decode->input_buffer.datasize,\ 350 (int)init_decode->input_buffer.mincount,\ 351 (int)init_decode->input_buffer.actualcount); 352 353 354 ioctl_msg.inputparam = &init_decode->input_buffer; 355 ioctl_msg.outputparam = NULL; 356 init_decode->input_buffer.actualcount = init_decode->input_buffer.mincount + 2; 357 358 if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ, 359 (void*)&ioctl_msg) < 0) 360 { 361 DEBUG_PRINT("\n Set Buffer Requirements Failed"); 362 return -1; 363 } 364 365 366 DEBUG_PRINT("\n Query output bufffer requirements"); 367 ioctl_msg.inputparam = NULL; 368 ioctl_msg.outputparam = &init_decode->output_buffer; 369 370 if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ, 371 (void*)&ioctl_msg) < 0) 372 { 373 DEBUG_PRINT("\n Requesting for output buffer requirements failed"); 374 return -1; 375 } 376 377 DEBUG_PRINT("\n output Size=%d min count =%d actual count = %d", \ 378 (int)init_decode->output_buffer.datasize,\ 379 (int)init_decode->output_buffer.mincount,\ 380 (int)init_decode->output_buffer.actualcount); 381 382 /*Create Queue related data structures*/ 383 queue_ptr = &init_decode->queue_context; 384 queue_ptr->commandq_size = 50; 385 queue_ptr->dataq_size = 50; 386 387 sem_init(&queue_ptr->sem_message,0, 0); 388 sem_init(&init_decode->sem_synchronize,0, 0); 389 390 pthread_mutexattr_init (&init_values); 391 pthread_mutex_init (&queue_ptr->mutex,&init_values); 392 pthread_mutex_init (&read_lock,&init_values); 393 DEBUG_PRINT("\n create Queues"); 394 queue_ptr->ptr_cmdq = (struct video_msgq*) \ 395 calloc (sizeof (struct video_msgq), 396 queue_ptr->commandq_size); 397 queue_ptr->ptr_dataq = (struct video_msgq*) \ 398 calloc (sizeof (struct video_msgq), 399 queue_ptr->dataq_size 400 ); 401 402 if ( queue_ptr->ptr_cmdq == NULL || 403 queue_ptr->ptr_dataq == NULL 404 ) 405 { 406 return -1; 407 } 408 DEBUG_PRINT("\n create Threads"); 409 /*Create two threads*/ 410 if ( (pthread_create (&init_decode->videothread_id,NULL,video_thread, 411 init_decode) < 0) || 412 (pthread_create (&init_decode->asyncthread_id,NULL,async_thread, 413 init_decode) < 0) 414 ) 415 { 416 return -1; 417 } 418 419 return 1; 420 } 421 422 423 424 int free_buffer ( unsigned int buffer_dir, 425 struct video_encoder_context *encoder_context 426 ) 427 { 428 unsigned int buffercount = 0,i=0; 429 struct venc_bufferpayload **ptemp = NULL; 430 431 if (encoder_context == NULL) 432 { 433 return -1; 434 } 435 436 if (buffer_dir == INPUT_BUFFER && encoder_context->ptr_inputbuffer) 437 { 438 buffercount = encoder_context->input_buffer.actualcount; 439 ptemp = encoder_context->ptr_inputbuffer; 440 441 for (i=0;i<buffercount;i++) 442 { 443 if (ptemp [i]) 444 { 445 if (ptemp [i]->fd != -1) 446 { 447 munmap ( ptemp [i]->pbuffer,ptemp [i]->maped_size); 448 ptemp [i]->pbuffer = NULL; 449 close (ptemp [i]->fd); 450 } 451 free (ptemp [i]); 452 ptemp [i] = NULL; 453 } 454 } 455 free (encoder_context->ptr_inputbuffer); 456 encoder_context->ptr_inputbuffer = NULL; 457 } 458 else if ( buffer_dir == OUTPUT_BUFFER && encoder_context->ptr_outputbuffer ) 459 { 460 buffercount = encoder_context->output_buffer.actualcount; 461 ptemp = encoder_context->ptr_outputbuffer; 462 463 if (ptemp) 464 { 465 for (i=0;i<buffercount;i++) 466 { 467 if (ptemp [i]) 468 { 469 if (ptemp [i]->fd != -1) 470 { 471 munmap ( ptemp [i]->pbuffer,ptemp [i]->maped_size); 472 ptemp [i]->pbuffer = NULL; 473 close (ptemp [i]->fd); 474 } 475 free (ptemp [i]); 476 ptemp [i] = NULL; 477 } 478 } 479 free (ptemp); 480 encoder_context->ptr_outputbuffer = NULL; 481 } 482 } 483 484 return 1; 485 } 486 487 int allocate_buffer ( unsigned int buffer_dir, 488 struct video_encoder_context *encoder_context 489 ) 490 { 491 struct venc_bufferpayload **ptemp = NULL; 492 struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; 493 unsigned int buffercount = 0,i=0,alignedsize=0; 494 unsigned int buffersize = 0; 495 496 if ( encoder_context == NULL) 497 { 498 DEBUG_PRINT ("\nallocate_buffer: context is NULL"); 499 return -1; 500 } 501 502 if ( buffer_dir == INPUT_BUFFER ) 503 { 504 /*Check if buffers are allocated*/ 505 if (encoder_context->ptr_inputbuffer != NULL) 506 { 507 DEBUG_PRINT ("\nallocate_buffer: encoder_context->ptr_inputbuffer is set"); 508 return -1; 509 } 510 511 buffercount = encoder_context->input_buffer.actualcount; 512 alignedsize = encoder_context->input_buffer.alignment; 513 buffersize = encoder_context->input_buffer.datasize; 514 buffersize = (buffersize + alignedsize) & (~alignedsize); 515 } 516 else if (buffer_dir == OUTPUT_BUFFER) 517 { 518 /*Check if buffers are allocated*/ 519 if (encoder_context->ptr_outputbuffer != NULL) 520 { 521 DEBUG_PRINT ("\nallocate_buffer: Double allcoate output"); 522 return -1; 523 } 524 525 buffercount = encoder_context->output_buffer.actualcount; 526 alignedsize = encoder_context->output_buffer.alignment; 527 buffersize = encoder_context->output_buffer.datasize; 528 buffersize = (buffersize + alignedsize) & (~alignedsize); 529 530 } 531 else 532 { 533 DEBUG_PRINT ("\nallocate_buffer: Wrong buffer directions"); 534 return -1; 535 } 536 537 ptemp = (struct venc_bufferpayload **)\ 538 calloc (sizeof (struct venc_bufferpayload *),buffercount); 539 540 if (ptemp == NULL) 541 { 542 DEBUG_PRINT ("\nallocate_buffer: venc_bufferpayload failure"); 543 return -1; 544 } 545 546 547 if (buffer_dir == OUTPUT_BUFFER) 548 { 549 DEBUG_PRINT ("\nallocate_buffer: OUT"); 550 encoder_context->ptr_outputbuffer = ptemp; 551 } 552 else 553 { 554 DEBUG_PRINT ("\nallocate_buffer: IN"); 555 encoder_context->ptr_inputbuffer = ptemp; 556 } 557 558 /*Allocate buffer headers*/ 559 for (i=0; i< buffercount; i++) 560 { 561 ptemp [i] = (struct venc_bufferpayload*)\ 562 calloc (sizeof (struct venc_bufferpayload),1); 563 564 if (ptemp [i] == NULL) 565 { 566 DEBUG_PRINT ("\nallocate_buffer: ptemp [i] calloc failure"); 567 return -1; 568 } 569 ptemp [i]->fd = -1; 570 } 571 572 for (i=0; i< buffercount; i++) 573 { 574 ptemp [i]->fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC); 575 576 if (ptemp [i]->fd < 0) 577 { 578 DEBUG_PRINT ("\nallocate_buffer: open pmem failed"); 579 return -1; 580 } 581 582 ptemp [i]->pbuffer = mmap(NULL,clp2(buffersize),PROT_READ|PROT_WRITE, 583 MAP_SHARED,ptemp [i]->fd,0); 584 DEBUG_PRINT ("\n pmem fd = %d virt addr = %p",ptemp [i]->fd,\ 585 ptemp [i]->pbuffer); 586 if (ptemp [i]->pbuffer == MAP_FAILED) 587 { 588 ptemp [i]->pbuffer = NULL; 589 DEBUG_PRINT ("\nallocate_buffer: MMAP failed"); 590 return -1; 591 } 592 ptemp [i]->nsize = buffersize; 593 ptemp [i]->maped_size = clp2 (buffersize); 594 595 ioctl_msg.inputparam = ptemp [i]; 596 ioctl_msg.outputparam = NULL; 597 598 if (buffer_dir == OUTPUT_BUFFER) 599 { 600 if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER, 601 &ioctl_msg) < 0) 602 { 603 DEBUG_PRINT ("\nallocate_buffer: Set Output Buffer IOCTL failed"); 604 return -1; 605 } 606 } 607 else 608 { 609 if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_SET_INPUT_BUFFER, 610 &ioctl_msg) < 0) 611 { 612 DEBUG_PRINT ("\nallocate_buffer: Set input Buffer IOCTL failed"); 613 return -1; 614 } 615 } 616 617 } 618 DEBUG_PRINT ("\nallocate_buffer: Success"); 619 return 1; 620 } 621 622 623 624 int start_encoding (struct video_encoder_context *encoder_context) 625 { 626 struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; 627 struct venc_buffer enc_buffer; 628 unsigned int i = 0; 629 unsigned int data_len =0; 630 631 632 if (encoder_context == NULL) 633 { 634 return -1; 635 } 636 637 if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_CMD_START, 638 NULL) < 0) 639 { 640 DEBUG_PRINT("\n Start failed"); 641 return -1; 642 } 643 644 DEBUG_PRINT("\n Start Issued successfully waiting for Start Done"); 645 /*Wait for Start command response*/ 646 sem_wait (&encoder_context->sem_synchronize); 647 648 /*Push output Buffers*/ 649 i = 0; 650 while (i < encoder_context->output_buffer.actualcount) 651 { 652 enc_buffer.clientdata = (void *)encoder_context->ptr_outputbuffer [i]; 653 enc_buffer.flags = 0; 654 enc_buffer.size = encoder_context->ptr_outputbuffer [i]->nsize; 655 enc_buffer.len = 0; 656 enc_buffer.ptrbuffer = encoder_context->ptr_outputbuffer [i]->pbuffer; 657 enc_buffer.offset = 0; 658 enc_buffer.timestamp = 0; 659 660 DEBUG_PRINT ("\n Client Data on output = %p",(void *)enc_buffer.clientdata); 661 ioctl_msg.inputparam = &enc_buffer; 662 ioctl_msg.outputparam = NULL; 663 664 if (ioctl (encoder_context->video_driver_fd, 665 VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0) 666 { 667 DEBUG_PRINT("\n fill output frame failed"); 668 return -1; 669 } 670 i++; 671 } 672 673 674 /*push input buffers*/ 675 i = 0; 676 while (i < encoder_context->input_buffer.actualcount) 677 { 678 DEBUG_PRINT("\n Read Frame from File"); 679 680 enc_buffer.clientdata = (void *)encoder_context->ptr_inputbuffer [i]; 681 enc_buffer.flags = 0; 682 enc_buffer.size = encoder_context->ptr_inputbuffer [i]->nsize; 683 enc_buffer.len = 0; 684 enc_buffer.ptrbuffer = encoder_context->ptr_inputbuffer [i]->pbuffer; 685 enc_buffer.offset = 0; 686 enc_buffer.timestamp = total_frames * 687 ((encoder_context->fps_den * 1000000)/encoder_context->fps_num); 688 enc_buffer.len = (encoder_context->input_height * 689 encoder_context->input_width *3)/2; 690 data_len = read_frame ( enc_buffer.ptrbuffer, 691 enc_buffer.len, 692 encoder_context->inputBufferFile); 693 if (data_len == 0) 694 { 695 DEBUG_PRINT("\n Length is zero error"); 696 return -1; 697 } 698 enc_buffer.len = data_len; 699 DEBUG_PRINT("\n Read Frame from File szie = %d",(int)data_len); 700 701 DEBUG_PRINT ("\n Client Data on output = %p",(void *)enc_buffer.clientdata); 702 ioctl_msg.inputparam = &enc_buffer; 703 ioctl_msg.outputparam = NULL; 704 705 if (ioctl (encoder_context->video_driver_fd, 706 VEN_IOCTL_CMD_ENCODE_FRAME,&ioctl_msg) < 0) 707 { 708 DEBUG_PRINT("\n Encode input frame failed"); 709 return -1; 710 } 711 total_frames++; 712 i++; 713 } 714 DEBUG_PRINT ("\n Wait for EOS"); 715 /*Wait for EOS or Error condition*/ 716 sem_wait (&encoder_context->sem_synchronize); 717 DEBUG_PRINT ("\n Reached EOS"); 718 719 return 1; 720 } 721 722 int stop_encoding (struct video_encoder_context *encoder_context) 723 { 724 struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; 725 struct venc_bufferflush buffer_flush; 726 727 if (encoder_context == NULL) 728 { 729 return -1; 730 } 731 buffer_flush.flush_mode = VEN_FLUSH_INPUT; 732 ioctl_msg.inputparam = &buffer_flush; 733 ioctl_msg.outputparam = NULL; 734 735 if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_FLUSH, 736 &ioctl_msg) < 0) 737 { 738 DEBUG_PRINT("\n Flush input failed"); 739 } 740 else 741 { 742 sem_wait (&encoder_context->sem_synchronize); 743 } 744 745 buffer_flush.flush_mode = VEN_FLUSH_OUTPUT; 746 ioctl_msg.inputparam = &buffer_flush; 747 ioctl_msg.outputparam = NULL; 748 749 if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_FLUSH, 750 &ioctl_msg) < 0) 751 { 752 DEBUG_PRINT("\n Flush output failed"); 753 } 754 else 755 { 756 sem_wait (&encoder_context->sem_synchronize); 757 } 758 759 DEBUG_PRINT("\n Stop VEN_IOCTL_CMD_STOP"); 760 if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_STOP,NULL) < 0) 761 { 762 DEBUG_PRINT("\n Stop failed"); 763 } 764 else 765 { 766 sem_wait (&encoder_context->sem_synchronize); 767 } 768 return 1; 769 } 770 771 int deinit_encoder (struct video_encoder_context *init_decode) 772 { 773 if (init_decode == NULL) 774 { 775 return -1; 776 } 777 778 /*Close the driver*/ 779 if (init_decode->video_driver_fd != -1) 780 { 781 close (init_decode->video_driver_fd); 782 } 783 784 if (init_decode->queue_context.ptr_cmdq) 785 { 786 free (init_decode->queue_context.ptr_cmdq); 787 init_decode->queue_context.ptr_cmdq = NULL; 788 } 789 790 if (init_decode->queue_context.ptr_dataq) 791 { 792 free (init_decode->queue_context.ptr_dataq); 793 init_decode->queue_context.ptr_dataq = NULL; 794 } 795 796 sem_destroy (&init_decode->queue_context.sem_message); 797 sem_destroy (&init_decode->sem_synchronize); 798 799 pthread_mutex_destroy(&init_decode->queue_context.mutex); 800 pthread_mutex_destroy (&read_lock); 801 802 return 1; 803 } 804 805 static void* video_thread (void *context) 806 { 807 struct video_encoder_context *encoder_context = NULL; 808 struct video_msgq *queueitem = NULL; 809 struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; 810 struct venc_bufferpayload *tempbuffer = NULL; 811 struct venc_buffer enc_buffer; 812 unsigned int data_len =0; 813 814 815 if (context == NULL) 816 { 817 DEBUG_PRINT("\n video thread recieved NULL context"); 818 return NULL; 819 } 820 encoder_context = (struct video_encoder_context *) context; 821 822 /* Thread function which will accept commands from async thread 823 * or main thread 824 */ 825 while (1) 826 { 827 queueitem = queue_get_cmd (&encoder_context ->queue_context); 828 if (queueitem != NULL) 829 { 830 switch (queueitem->cmd) 831 { 832 case VEN_MSG_START: 833 DEBUG_PRINT("\n recived start done command"); 834 sem_post (&encoder_context->sem_synchronize); 835 break; 836 837 case VEN_MSG_STOP: 838 DEBUG_PRINT("\n recieved stop done"); 839 sem_post (&encoder_context->sem_synchronize); 840 break; 841 842 case VEN_MSG_INPUT_BUFFER_DONE: 843 844 tempbuffer = (struct venc_bufferpayload *)queueitem->clientdata; 845 if (tempbuffer == NULL) 846 { 847 DEBUG_PRINT("\n FATAL ERROR input buffer address is bad"); 848 sem_post (&encoder_context->sem_synchronize); 849 break; 850 } 851 tempbuffer->filled_len = (encoder_context->input_height * 852 encoder_context->input_width *3)/2; 853 854 data_len = read_frame ( tempbuffer->pbuffer, 855 tempbuffer->filled_len, 856 encoder_context->inputBufferFile); 857 858 if (data_len == 0) 859 { 860 DEBUG_PRINT ("\n End of stream reached"); 861 sem_post (&encoder_context->sem_synchronize); 862 break; 863 } 864 enc_buffer.clientdata = (void *)tempbuffer; 865 enc_buffer.flags = 0; 866 enc_buffer.ptrbuffer = tempbuffer->pbuffer; 867 enc_buffer.size = tempbuffer->nsize; 868 enc_buffer.len = tempbuffer->filled_len; 869 enc_buffer.offset = 0; 870 enc_buffer.timestamp = total_frames * 871 ((encoder_context->fps_den * 1000000)/encoder_context->fps_num); 872 873 /*TODO: Time stamp needs to be updated*/ 874 ioctl_msg.inputparam = &enc_buffer; 875 ioctl_msg.outputparam = NULL; 876 total_frames++; 877 if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_ENCODE_FRAME, 878 &ioctl_msg) < 0) 879 { 880 DEBUG_PRINT("\n Decoder frame failed"); 881 sem_post (&encoder_context->sem_synchronize); 882 } 883 DEBUG_PRINT("\n Input buffer done send next buffer current value = %d",\ 884 total_frames); 885 break; 886 887 case VEN_MSG_OUTPUT_BUFFER_DONE: 888 889 tempbuffer = (struct venc_bufferpayload *)queueitem->clientdata; 890 if (tempbuffer == NULL) 891 { 892 DEBUG_PRINT("\n FATAL ERROR input buffer address is bad"); 893 sem_post (&encoder_context->sem_synchronize); 894 break; 895 } 896 897 if (encoder_context->outputBufferFile != NULL) 898 { 899 fwrite (tempbuffer->pbuffer,1,tempbuffer->filled_len, 900 encoder_context->outputBufferFile); 901 } 902 903 904 DEBUG_PRINT("\n recieved output buffer consume outbuffer"); 905 DEBUG_PRINT("\nValues outputbuffer->bufferaddr = %p",\ 906 tempbuffer->pbuffer); 907 enc_buffer.clientdata = (void *)tempbuffer; 908 enc_buffer.flags = 0; 909 enc_buffer.size = tempbuffer->nsize; 910 enc_buffer.len = 0; 911 enc_buffer.ptrbuffer = tempbuffer->pbuffer; 912 enc_buffer.offset = 0; 913 enc_buffer.timestamp = 0; 914 915 ioctl_msg.inputparam = &enc_buffer; 916 ioctl_msg.outputparam = NULL; 917 918 if (ioctl (encoder_context->video_driver_fd, 919 VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0) 920 { 921 DEBUG_PRINT("\n Decoder frame failed"); 922 return NULL; 923 } 924 925 break; 926 927 case VEN_MSG_FLUSH_INPUT_DONE: 928 DEBUG_PRINT("\n Flush input complete"); 929 sem_post (&encoder_context->sem_synchronize); 930 break; 931 932 case VEN_MSG_FLUSH_OUPUT_DONE: 933 DEBUG_PRINT("\n Flush output complete"); 934 sem_post (&encoder_context->sem_synchronize); 935 break; 936 } 937 } 938 else 939 { 940 DEBUG_PRINT("\n Error condition recieved NULL from Queue"); 941 } 942 943 if (queueitem->cmd == VEN_MSG_STOP) 944 { 945 DEBUG_PRINT("\n Playback has ended thread will exit"); 946 return NULL; 947 } 948 } 949 } 950 951 static void* async_thread (void *context) 952 { 953 struct video_encoder_context *encoder_context = NULL; 954 struct video_msgq queueitem ; 955 struct venc_msg venc_msg; 956 struct venc_bufferpayload *tempbuffer = NULL; 957 struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; 958 int result = -1; 959 960 if (context == NULL) 961 { 962 DEBUG_PRINT("\n aynsc thread recieved NULL context"); 963 return NULL; 964 } 965 encoder_context = (struct video_encoder_context *) context; 966 DEBUG_PRINT("\n Entering the async thread"); 967 968 while (1) 969 { 970 ioctl_msg.inputparam = NULL; 971 ioctl_msg.outputparam = (void*)&venc_msg; 972 DEBUG_PRINT ("\n Sizeof venc_msginfo = %d ",sizeof (venc_msg)); 973 DEBUG_PRINT("\n Address of Venc msg in async thread %p",\ 974 ioctl_msg.outputparam); 975 if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_CMD_READ_NEXT_MSG,\ 976 (void*)&ioctl_msg) < 0) 977 { 978 DEBUG_PRINT("\n Error in ioctl read next msg"); 979 } 980 else 981 { 982 switch (venc_msg.msgcode) 983 { 984 case VEN_MSG_START: 985 case VEN_MSG_STOP: 986 case VEN_MSG_INDICATION: 987 DEBUG_PRINT("\nSTOP/START Indiacation"); 988 queueitem.cmd = venc_msg.msgcode; 989 queueitem.status = venc_msg.statuscode; 990 queueitem.clientdata = NULL; 991 break; 992 993 case VEN_MSG_INPUT_BUFFER_DONE: 994 DEBUG_PRINT("\nINPUT buffer done Indiacation"); 995 queueitem.cmd = venc_msg.msgcode; 996 queueitem.status = venc_msg.statuscode; 997 queueitem.clientdata = (void *)venc_msg.buf.clientdata; 998 DEBUG_PRINT("\nInput Client data pointer is %p",queueitem.clientdata); 999 tempbuffer = (struct venc_bufferpayload *) queueitem.clientdata; 1000 DEBUG_PRINT ("\n Input Address of tempbuffer %p",tempbuffer); 1001 tempbuffer->filled_len = venc_msg.buf.len; 1002 DEBUG_PRINT ("\n Input value of tempbuffer tempbuffer->filled_len %d",(int)tempbuffer->filled_len); 1003 break; 1004 case VEN_MSG_OUTPUT_BUFFER_DONE: 1005 DEBUG_PRINT("\nOUPUT buffer done Indiacation"); 1006 queueitem.cmd = venc_msg.msgcode; 1007 queueitem.status = venc_msg.statuscode; 1008 queueitem.clientdata = (void *)venc_msg.buf.clientdata; 1009 DEBUG_PRINT("\nOutput Client data pointer is %p",queueitem.clientdata); 1010 tempbuffer = (struct venc_bufferpayload *) queueitem.clientdata; 1011 DEBUG_PRINT ("\n Output Address of tempbuffer %p",tempbuffer); 1012 tempbuffer->filled_len = venc_msg.buf.len; 1013 DEBUG_PRINT ("\n Output value of tempbuffer tempbuffer->filled_len %d",(int)tempbuffer->filled_len); 1014 break; 1015 1016 default: 1017 DEBUG_PRINT("\nIn Default of get next message %d",(int)venc_msg.msgcode); 1018 queueitem.cmd = venc_msg.msgcode; 1019 queueitem.status = venc_msg.statuscode; 1020 queueitem.clientdata = NULL; 1021 break; 1022 } 1023 result = queue_post_cmdq (&encoder_context->queue_context,&queueitem); 1024 while (result == 0) 1025 { 1026 result = queue_post_cmdq (&encoder_context->queue_context,&queueitem); 1027 } 1028 1029 if (result == -1) 1030 { 1031 DEBUG_PRINT("\n FATAL ERROR WITH Queue"); 1032 } 1033 } 1034 if (venc_msg.msgcode == VEN_MSG_STOP) 1035 { 1036 /*Thread can exit at this point*/ 1037 return NULL; 1038 } 1039 } 1040 } 1041 1042 1043 static unsigned int read_frame (unsigned char *dataptr, unsigned int length, 1044 FILE * inputBufferFile) 1045 { 1046 1047 unsigned int readOffset = 0; 1048 int bytes_read = 0; 1049 unsigned int code = 0; 1050 int found = 0; 1051 1052 DEBUG_PRINT ("\n Inside the readframe"); 1053 1054 if (dataptr == NULL && length == 0) 1055 { 1056 DEBUG_PRINT ("\n dataptr = %p length = %d",dataptr,(int)length); 1057 return 0; 1058 } 1059 1060 pthread_mutex_lock(&read_lock); 1061 bytes_read = fread(&dataptr[readOffset],1,length,inputBufferFile); 1062 pthread_mutex_unlock(&read_lock); 1063 1064 return bytes_read; 1065 } 1066