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