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