1/*-------------------------------------------------------------------------- 2Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved. 3 4Redistribution and use in source and binary forms, with or without 5modification, 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 16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 20CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27--------------------------------------------------------------------------*/ 28#include <stdio.h> 29#include <stddef.h> 30#include <stdlib.h> 31#include <fcntl.h> 32#include <stdarg.h> 33#include <string.h> 34#include <errno.h> 35#include <unistd.h> 36#include <pthread.h> 37#include <ctype.h> 38#include <sys/stat.h> 39#include <sys/ioctl.h> 40#include <sys/mman.h> 41#include <sys/time.h> 42#include <sys/poll.h> 43#include <stdint.h> 44 45#include "frameparser.h" 46 47#ifdef _ANDROID_ 48 extern "C"{ 49 #include<utils/Log.h> 50 } 51#endif//_ANDROID_ 52 53#undef DEBUG_PRINT_LOW 54#undef DEBUG_PRINT_HIGH 55#undef DEBUG_PRINT_ERROR 56 57#define DEBUG_PRINT_LOW ALOGV 58#define DEBUG_PRINT_HIGH ALOGV 59#define DEBUG_PRINT_ERROR ALOGE 60 61static unsigned char H264_mask_code[4] = {0xFF,0xFF,0xFF,0xFF}; 62static unsigned char H264_start_code[4] = {0x00,0x00,0x00,0x01}; 63 64static unsigned char MPEG4_start_code[4] = {0x00,0x00,0x01,0xB6}; 65static unsigned char MPEG4_mask_code[4] = {0xFF,0xFF,0xFF,0xFF}; 66 67static unsigned char H263_start_code[4] = {0x00,0x00,0x80,0x00}; 68static unsigned char H263_mask_code[4] = {0xFF,0xFF,0xFC,0x00}; 69 70static unsigned char VC1_AP_start_code[4] = {0x00,0x00,0x01,0x0C}; 71static unsigned char VC1_AP_mask_code[4] = {0xFF,0xFF,0xFF,0xFC}; 72 73static unsigned char MPEG2_start_code[4] = {0x00, 0x00, 0x01, 0x00}; 74static unsigned char MPEG2_mask_code[4] = {0xFF, 0xFF, 0xFF, 0xFF}; 75 76frame_parse::frame_parse():parse_state(A0), 77 last_byte_h263(0), 78 state_nal(NAL_LENGTH_ACC), 79 nal_length(0), 80 accum_length(0), 81 bytes_tobeparsed(0), 82 mutils(NULL), 83 start_code(NULL), 84 mask_code(NULL), 85 header_found(false), 86 skip_frame_boundary(false) 87{ 88} 89 90frame_parse::~frame_parse () 91{ 92 if (mutils) 93 delete mutils; 94 95 mutils = NULL; 96} 97 98int frame_parse::init_start_codes (codec_type codec_type_parse) 99{ 100 /*Check if Codec Type is proper and we are in proper state*/ 101 if (codec_type_parse > CODEC_TYPE_MAX || parse_state != A0) 102 { 103 return -1; 104 } 105 106 switch (codec_type_parse) 107 { 108 case CODEC_TYPE_MPEG4: 109 start_code = MPEG4_start_code; 110 mask_code = MPEG4_mask_code; 111 break; 112 case CODEC_TYPE_H263: 113 start_code = H263_start_code; 114 mask_code = H263_mask_code; 115 break; 116 case CODEC_TYPE_H264: 117 start_code = H264_start_code; 118 mask_code = H264_mask_code; 119 break; 120 case CODEC_TYPE_VC1: 121 start_code = VC1_AP_start_code; 122 mask_code = VC1_AP_mask_code; 123 break; 124 case CODEC_TYPE_MPEG2: 125 start_code = MPEG2_start_code; 126 mask_code = MPEG2_mask_code; 127 break; 128 } 129 return 1; 130} 131 132 133int frame_parse::init_nal_length (unsigned int nal_len) 134{ 135 if (nal_len == 0 || nal_len > 4 || state_nal != NAL_LENGTH_ACC) 136 { 137 return -1; 138 } 139 nal_length = nal_len; 140 141 return 1; 142} 143 144int frame_parse::parse_sc_frame ( OMX_BUFFERHEADERTYPE *source, 145 OMX_BUFFERHEADERTYPE *dest , 146 OMX_U32 *partialframe) 147{ 148 OMX_U8 *pdest = NULL,*psource = NULL, match_found = FALSE, is_byte_match = 0; 149 OMX_U32 dest_len =0, source_len = 0, temp_len = 0; 150 OMX_U32 parsed_length = 0,i=0; 151 int residue_byte = 0; 152 153 if (source == NULL || dest == NULL || partialframe == NULL) 154 { 155 return -1; 156 } 157 158 /*Calculate how many bytes are left in source and destination*/ 159 dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); 160 psource = source->pBuffer + source->nOffset; 161 pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset); 162 source_len = source->nFilledLen; 163 164 /*Need Minimum Start Code size for destination to copy atleast Start code*/ 165 if ((start_code == H263_start_code && dest_len < 3) || 166 (start_code != H263_start_code && dest_len < 4) || (source_len == 0)) 167 { 168 DEBUG_PRINT_LOW("\n FrameParser: dest_len %d source_len %d",dest_len,source_len); 169 if (source_len == 0 && (source->nFlags & 0x01)) 170 { 171 DEBUG_PRINT_LOW("\n FrameParser: EOS rxd!! Notify it as a complete frame"); 172 *partialframe = 0; 173 return 1; 174 } 175 DEBUG_PRINT_LOW("\n FrameParser: Bitstream Parsing error"); 176 return -1; 177 } 178 179 /*Check if State of the previous find is a Start code*/ 180 if (parse_state == A4 || parse_state == A5) 181 { 182 /*Check for minimun size should be 4*/ 183 dest->nFlags = source->nFlags; 184 dest->nTimeStamp = source->nTimeStamp; 185 186 if(start_code == H263_start_code) 187 { 188 memcpy (pdest,start_code,2); 189 pdest[2] = last_byte_h263; 190 dest->nFilledLen += 3; 191 pdest += 3; 192 } 193 else 194 { 195 memcpy (pdest,start_code,4); 196 if (start_code == VC1_AP_start_code 197 || start_code == MPEG4_start_code 198 || start_code == MPEG2_start_code) 199 { 200 pdest[3] = last_byte; 201 update_skip_frame(); 202 } 203 dest->nFilledLen += 4; 204 pdest += 4; 205 } 206 parse_state = A0; 207 } 208 209 /*Entry State Machine*/ 210 while ( source->nFilledLen > 0 && parse_state != A0 211 && parse_state != A4 && parse_state != A5 && dest_len > 0 212 ) 213 { 214 //printf ("\n In the Entry Loop"); 215 switch (parse_state) 216 { 217 case A3: 218 parse_additional_start_code(psource,&parsed_length); 219 if (parse_state == A4) { 220 source->nFilledLen--; 221 source->nOffset++; 222 psource++; 223 break; 224 } 225 /*If fourth Byte is matching then start code is found*/ 226 if ((*psource & mask_code [3]) == start_code [3]) 227 { 228 parse_state = A4; 229 last_byte = *psource; 230 source->nFilledLen--; 231 source->nOffset++; 232 psource++; 233 } 234 else if ((start_code [1] == start_code [0]) && (start_code [2] == start_code [1])) 235 { 236 parse_state = A2; 237 memcpy (pdest,start_code,1); 238 pdest++; 239 dest->nFilledLen++; 240 dest_len--; 241 } 242 else if (start_code [2] == start_code [0]) 243 { 244 parse_state = A1; 245 memcpy (pdest,start_code,2); 246 pdest += 2; 247 dest->nFilledLen += 2; 248 dest_len -= 2; 249 } 250 else 251 { 252 parse_state = A0; 253 memcpy (pdest,start_code,3); 254 pdest += 3; 255 dest->nFilledLen +=3; 256 dest_len -= 3; 257 } 258 break; 259 260 case A2: 261 is_byte_match = ((*psource & mask_code [2]) == start_code [2]); 262 match_found = FALSE; 263 264 if (start_code == H263_start_code) 265 { 266 if (is_byte_match) 267 { 268 last_byte_h263 = *psource; 269 parse_state = A5; 270 match_found = TRUE; 271 } 272 } 273 else if (start_code == H264_start_code && 274 (*psource & mask_code [3]) == start_code [3]) 275 { 276 parse_state = A5; 277 match_found = TRUE; 278 } 279 else 280 { 281 if (is_byte_match) 282 { 283 parse_state = A3; 284 match_found = TRUE; 285 } 286 } 287 288 if (match_found) 289 { 290 source->nFilledLen--; 291 source->nOffset++; 292 psource++; 293 } 294 else if (start_code [1] == start_code [0]) 295 { 296 parse_state = A1; 297 memcpy (pdest,start_code,1); 298 dest->nFilledLen +=1; 299 dest_len--; 300 pdest++; 301 } 302 else 303 { 304 parse_state = A0; 305 memcpy (pdest,start_code,2); 306 dest->nFilledLen +=2; 307 dest_len -= 2; 308 pdest += 2; 309 } 310 311 break; 312 313 case A1: 314 if ((*psource & mask_code [1]) == start_code [1]) 315 { 316 parse_state = A2; 317 source->nFilledLen--; 318 source->nOffset++; 319 psource++; 320 } 321 else 322 { 323 memcpy (pdest,start_code,1); 324 dest->nFilledLen +=1; 325 pdest++; 326 dest_len--; 327 parse_state = A0; 328 } 329 break; 330 case A4: 331 case A0: 332 break; 333 } 334 dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); 335 } 336 337 if (parse_state == A4 || parse_state == A5) 338 { 339 *partialframe = 0; 340 check_skip_frame_boundary(partialframe); 341 DEBUG_PRINT_LOW("\n FrameParser: Parsed Len = %d", dest->nFilledLen); 342 return 1; 343 } 344 345 /*Partial Frame is true*/ 346 *partialframe = 1; 347 348 /*Calculate how many bytes are left in source and destination*/ 349 dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); 350 psource = source->pBuffer + source->nOffset; 351 pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset); 352 source_len = source->nFilledLen; 353 354 temp_len = (source_len < dest_len)?source_len:dest_len; 355 356 /*Check if entry state machine consumed source or destination*/ 357 if (temp_len == 0) 358 { 359 return 1; 360 } 361 362 /*Parsing State Machine*/ 363 while (parsed_length < temp_len) 364 { 365 switch (parse_state) 366 { 367 case A0: 368 if ((psource [parsed_length] & mask_code [0]) == start_code[0]) 369 { 370 parse_state = A1; 371 } 372 parsed_length++; 373 break; 374 case A1: 375 if ((psource [parsed_length] & mask_code [1]) == start_code [1]) 376 { 377 parsed_length++; 378 parse_state = A2; 379 } 380 else 381 { 382 parse_state = A0; 383 } 384 break; 385 case A2: 386 is_byte_match = ((psource[parsed_length] & mask_code [2]) == start_code [2]); 387 match_found = FALSE; 388 389 if (start_code == H263_start_code) 390 { 391 if (is_byte_match) 392 { 393 last_byte_h263 = psource[parsed_length]; 394 parse_state = A5; 395 match_found = TRUE; 396 } 397 } 398 else if (start_code == H264_start_code && 399 (psource[parsed_length] & mask_code [3]) == start_code [3]) 400 { 401 parse_state = A5; 402 match_found = TRUE; 403 } 404 else 405 { 406 if(is_byte_match) 407 { 408 parse_state = A3; 409 match_found = TRUE; 410 } 411 } 412 413 if (match_found) 414 { 415 parsed_length++; 416 } 417 else if (start_code [1] == start_code [0]) 418 { 419 parse_state = A1; 420 } 421 else 422 { 423 parse_state = A0; 424 } 425 426 break; 427 case A3: 428 parse_additional_start_code(psource,&parsed_length); 429 if (parse_state == A4) break; 430 431 if ((psource [parsed_length] & mask_code [3]) == start_code [3]) 432 { 433 last_byte = psource [parsed_length]; 434 parsed_length++; 435 parse_state = A4; 436 } 437 else if ((start_code [1] == start_code [0]) && (start_code [2] == start_code [1])) 438 { 439 parse_state = A2; 440 } 441 else if (start_code [2] == start_code [0]) 442 { 443 parse_state = A1; 444 } 445 else 446 { 447 parse_state = A0; 448 } 449 break; 450 } 451 452 /*Found the code break*/ 453 if (parse_state == A4 || parse_state == A5) 454 { 455 break; 456 } 457 } 458 459 /*Exit State Machine*/ 460 psource = source->pBuffer + source->nOffset; 461 switch (parse_state) 462 { 463 case A5: 464 *partialframe = 0; 465 check_skip_frame_boundary(partialframe); 466 if (parsed_length > 3) 467 { 468 memcpy (pdest,psource,(parsed_length-3)); 469 dest->nFilledLen += (parsed_length-3); 470 } 471 break; 472 case A4: 473 *partialframe = 0; 474 check_skip_frame_boundary(partialframe); 475 if (parsed_length > 4) 476 { 477 memcpy (pdest,psource,(parsed_length-4)); 478 dest->nFilledLen += (parsed_length-4); 479 } 480 break; 481 case A3: 482 if (parsed_length > 3) 483 { 484 memcpy (pdest,psource,(parsed_length-3)); 485 dest->nFilledLen += (parsed_length-3); 486 } 487 break; 488 case A2: 489 if (parsed_length > 2) 490 { 491 memcpy (pdest,psource,(parsed_length-2)); 492 dest->nFilledLen += (parsed_length-2); 493 } 494 break; 495 case A1: 496 if (parsed_length > 1) 497 { 498 memcpy (pdest,psource,(parsed_length-1)); 499 dest->nFilledLen += (parsed_length-1); 500 } 501 break; 502 case A0: 503 memcpy (pdest,psource,(parsed_length)); 504 dest->nFilledLen += (parsed_length); 505 break; 506 } 507 508 if (source->nFilledLen < parsed_length) 509 { 510 printf ("\n FATAL Error"); 511 return -1; 512 } 513 source->nFilledLen -= parsed_length; 514 source->nOffset += parsed_length; 515 516 return 1; 517} 518 519 520int frame_parse::parse_h264_nallength (OMX_BUFFERHEADERTYPE *source, 521 OMX_BUFFERHEADERTYPE *dest , 522 OMX_U32 *partialframe) 523{ 524 OMX_U8 *pdest = NULL,*psource = NULL; 525 OMX_U32 dest_len =0, source_len = 0, temp_len = 0,parsed_length = 0; 526 527 if (source == NULL || dest == NULL || partialframe == NULL) 528 { 529 return -1; 530 } 531 532 /*Calculate the length's*/ 533 dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); 534 source_len = source->nFilledLen; 535 536 if (dest_len < 4 || source_len == 0 || nal_length == 0) 537 { 538 DEBUG_PRINT_LOW("\n FrameParser: NAL Parsing Error! dest_len %d " 539 "source_len %d nal_length %d", dest_len, source_len, nal_length); 540 return -1; 541 } 542 *partialframe = 1; 543 temp_len = (source_len < dest_len)?source_len:dest_len; 544 psource = source->pBuffer + source->nOffset; 545 pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset); 546 547 /* Find the Bytes to Accumalte*/ 548 if (state_nal == NAL_LENGTH_ACC) 549 { 550 while (parsed_length < temp_len ) 551 { 552 bytes_tobeparsed |= (((OMX_U32)(*psource))) << (((nal_length-accum_length-1) << 3)); 553 554 /*COPY THE DATA FOR C-SIM TO BE REOMVED ON TARGET*/ 555 //*pdest = *psource; 556 accum_length++; 557 source->nFilledLen--; 558 source->nOffset++; 559 psource++; 560 //dest->nFilledLen++; 561 //pdest++; 562 parsed_length++; 563 564 if (accum_length == nal_length) 565 { 566 accum_length = 0; 567 state_nal = NAL_PARSING; 568 memcpy (pdest,H264_start_code,4); 569 dest->nFilledLen += 4; 570 break; 571 } 572 } 573 } 574 575 dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); 576 source_len = source->nFilledLen; 577 temp_len = (source_len < dest_len)?source_len:dest_len; 578 579 psource = source->pBuffer + source->nOffset; 580 pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset); 581 582 dest->nTimeStamp = source->nTimeStamp; 583 dest->nFlags = source->nFlags; 584 585 /*Already in Parsing state go ahead and copy*/ 586 if(state_nal == NAL_PARSING && temp_len > 0) 587 { 588 if (temp_len < bytes_tobeparsed) 589 { 590 memcpy (pdest,psource,temp_len); 591 dest->nFilledLen += temp_len; 592 source->nOffset += temp_len; 593 source->nFilledLen -= temp_len; 594 bytes_tobeparsed -= temp_len; 595 } 596 else 597 { 598 memcpy (pdest,psource,bytes_tobeparsed); 599 temp_len -= bytes_tobeparsed; 600 dest->nFilledLen += bytes_tobeparsed; 601 source->nOffset += bytes_tobeparsed; 602 source->nFilledLen -= bytes_tobeparsed; 603 bytes_tobeparsed = 0; 604 } 605 } 606 607 if (bytes_tobeparsed == 0 && state_nal == NAL_PARSING) 608 { 609 *partialframe = 0; 610 state_nal = NAL_LENGTH_ACC; 611 } 612 613 return 1; 614} 615 616void frame_parse::flush () 617{ 618 parse_state = A0; 619 state_nal = NAL_LENGTH_ACC; 620 accum_length = 0; 621 bytes_tobeparsed = 0; 622 header_found = false; 623 skip_frame_boundary = false; 624} 625 626void frame_parse::parse_additional_start_code(OMX_U8 *psource, 627 OMX_U32 *parsed_length) 628{ 629 630 if (((start_code == MPEG4_start_code) || 631 (start_code == MPEG2_start_code)) && 632 psource && 633 parsed_length) 634 { 635 OMX_U32 index = *parsed_length; 636 if ((start_code == MPEG4_start_code && 637 (psource [index] & 0xF0) == 0x20) || 638 (start_code == MPEG2_start_code && 639 psource [index] == 0xB3)) 640 { 641 if (header_found) 642 { 643 last_byte = psource [index]; 644 index++; 645 parse_state = A4; 646 } else 647 header_found = true; 648 } 649 *parsed_length = index; 650 } 651} 652 653void frame_parse::check_skip_frame_boundary(OMX_U32 *partialframe) 654{ 655 if ((start_code == MPEG4_start_code || 656 start_code == MPEG2_start_code) && 657 partialframe) { 658 659 *partialframe = 1; 660 if (!skip_frame_boundary) 661 *partialframe = 0; 662 skip_frame_boundary = false; 663 } 664} 665 666void frame_parse::update_skip_frame() 667{ 668 if (((start_code == MPEG4_start_code) && 669 ((last_byte & 0xF0) == 0x20)) || 670 ((start_code == MPEG2_start_code) && 671 (last_byte == 0xB3))) { 672 673 skip_frame_boundary = true; 674 } 675} 676