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