Home | History | Annotate | Download | only in src
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2010 - 2013, The Linux Foundation. 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 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 
     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 <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 
     62 static unsigned char H264_mask_code[4] = {0xFF,0xFF,0xFF,0xFF};
     63 static unsigned char H264_start_code[4] = {0x00,0x00,0x00,0x01};
     64 
     65 static unsigned char MPEG4_start_code[4] = {0x00,0x00,0x01,0xB6};
     66 static unsigned char MPEG4_mask_code[4] = {0xFF,0xFF,0xFF,0xFF};
     67 
     68 static unsigned char H263_start_code[4] = {0x00,0x00,0x80,0x00};
     69 static unsigned char H263_mask_code[4] = {0xFF,0xFF,0xFC,0x00};
     70 
     71 static unsigned char VC1_AP_start_code[4] = {0x00,0x00,0x01,0x0C};
     72 static unsigned char VC1_AP_mask_code[4] = {0xFF,0xFF,0xFF,0xFC};
     73 
     74 static unsigned char MPEG2_start_code[4] = {0x00, 0x00, 0x01, 0x00};
     75 static unsigned char MPEG2_mask_code[4] = {0xFF, 0xFF, 0xFF, 0xFF};
     76 
     77 frame_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 
     92 frame_parse::~frame_parse ()
     93 {
     94     if (mutils)
     95         delete mutils;
     96 
     97     mutils = NULL;
     98 }
     99 
    100 int 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 
    141 int 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 
    152 int 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     int bytes_to_skip = 0;
    431     switch (parse_state) {
    432         case A5:
    433             *partialframe = 0;
    434             check_skip_frame_boundary(partialframe);
    435             bytes_to_skip = 3;
    436             break;
    437         case A4:
    438             *partialframe = 0;
    439             check_skip_frame_boundary(partialframe);
    440             bytes_to_skip = 4;
    441             break;
    442         case A3:
    443             if (source->nFlags & OMX_BUFFERFLAG_EOS) {
    444                 bytes_to_skip = 0;
    445             } else {
    446                 bytes_to_skip = 3;
    447             }
    448             break;
    449         case A2:
    450             if (source->nFlags & OMX_BUFFERFLAG_EOS) {
    451                 bytes_to_skip = 0;
    452             } else {
    453                 bytes_to_skip = 2;
    454             }
    455             break;
    456         case A1:
    457             if (source->nFlags & OMX_BUFFERFLAG_EOS) {
    458                 bytes_to_skip = 0;
    459             } else {
    460                 bytes_to_skip = 1;
    461             }
    462             break;
    463         case A0:
    464             bytes_to_skip = 0;
    465             break;
    466     }
    467 
    468     if (source->nFilledLen < parsed_length) {
    469         printf ("\n FATAL Error");
    470         return -1;
    471     }
    472 
    473     if (parsed_length > bytes_to_skip) {
    474         memcpy (pdest, psource, (parsed_length-bytes_to_skip));
    475         dest->nFilledLen += (parsed_length-bytes_to_skip);
    476     }
    477 
    478     source->nFilledLen -= parsed_length;
    479     source->nOffset += parsed_length;
    480 
    481     return 1;
    482 }
    483 
    484 
    485 int frame_parse::parse_h264_nallength (OMX_BUFFERHEADERTYPE *source,
    486         OMX_BUFFERHEADERTYPE *dest ,
    487         OMX_U32 *partialframe)
    488 {
    489     OMX_U8 *pdest = NULL,*psource = NULL;
    490     OMX_U32 dest_len =0, source_len = 0, temp_len = 0,parsed_length = 0;
    491 
    492     if (source == NULL || dest == NULL || partialframe == NULL) {
    493         return -1;
    494     }
    495 
    496     /*Calculate the length's*/
    497     dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset);
    498     source_len = source->nFilledLen;
    499 
    500     if (dest_len < 4 || source_len == 0 || nal_length == 0) {
    501         DEBUG_PRINT_LOW("\n FrameParser: NAL Parsing Error! dest_len %d "
    502                 "source_len %d nal_length %d", dest_len, source_len, nal_length);
    503         return -1;
    504     }
    505 
    506     *partialframe = 1;
    507     temp_len = (source_len < dest_len)?source_len:dest_len;
    508     psource = source->pBuffer + source->nOffset;
    509     pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset);
    510 
    511     /* Find the Bytes to Accumalte*/
    512     if (state_nal == NAL_LENGTH_ACC) {
    513         while (parsed_length < temp_len ) {
    514             bytes_tobeparsed |= (((OMX_U32)(*psource))) << (((nal_length-accum_length-1) << 3));
    515 
    516             /*COPY THE DATA FOR C-SIM TO BE REOMVED ON TARGET*/
    517             //*pdest = *psource;
    518             accum_length++;
    519             source->nFilledLen--;
    520             source->nOffset++;
    521             psource++;
    522             //dest->nFilledLen++;
    523             //pdest++;
    524             parsed_length++;
    525 
    526             if (accum_length == nal_length) {
    527                 accum_length = 0;
    528                 state_nal = NAL_PARSING;
    529                 memcpy (pdest,H264_start_code,4);
    530                 dest->nFilledLen += 4;
    531                 break;
    532             }
    533         }
    534     }
    535 
    536     dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset);
    537     source_len = source->nFilledLen;
    538     temp_len = (source_len < dest_len)?source_len:dest_len;
    539 
    540     psource = source->pBuffer + source->nOffset;
    541     pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset);
    542 
    543     dest->nTimeStamp = source->nTimeStamp;
    544     dest->nFlags = source->nFlags;
    545 
    546     /*Already in Parsing state go ahead and copy*/
    547     if (state_nal == NAL_PARSING && temp_len > 0) {
    548         if (temp_len < bytes_tobeparsed) {
    549             memcpy (pdest,psource,temp_len);
    550             dest->nFilledLen += temp_len;
    551             source->nOffset += temp_len;
    552             source->nFilledLen -= temp_len;
    553             bytes_tobeparsed -= temp_len;
    554         } else {
    555             memcpy (pdest,psource,bytes_tobeparsed);
    556             temp_len -= bytes_tobeparsed;
    557             dest->nFilledLen += bytes_tobeparsed;
    558             source->nOffset += bytes_tobeparsed;
    559             source->nFilledLen -= bytes_tobeparsed;
    560             bytes_tobeparsed = 0;
    561         }
    562     }
    563 
    564     if (bytes_tobeparsed == 0 && state_nal == NAL_PARSING) {
    565         *partialframe = 0;
    566         state_nal = NAL_LENGTH_ACC;
    567     }
    568 
    569     return 1;
    570 }
    571 
    572 void frame_parse::flush ()
    573 {
    574     parse_state = A0;
    575     state_nal = NAL_LENGTH_ACC;
    576     accum_length = 0;
    577     bytes_tobeparsed = 0;
    578     header_found = false;
    579     skip_frame_boundary = false;
    580 }
    581 
    582 void frame_parse::parse_additional_start_code(OMX_U8 *psource,
    583         OMX_U32 *parsed_length)
    584 {
    585 
    586     if (((start_code == MPEG4_start_code) ||
    587                 (start_code == MPEG2_start_code)) &&
    588             psource &&
    589             parsed_length) {
    590         OMX_U32 index = *parsed_length;
    591 
    592         if ((start_code == MPEG4_start_code &&
    593                     (psource [index] & 0xF0) == 0x20) ||
    594                 (start_code == MPEG2_start_code &&
    595                  psource [index] == 0xB3)) {
    596             if (header_found) {
    597                 last_byte = psource [index];
    598                 index++;
    599                 parse_state = A4;
    600             } else
    601                 header_found = true;
    602         }
    603 
    604         *parsed_length = index;
    605     }
    606 }
    607 
    608 void frame_parse::check_skip_frame_boundary(OMX_U32 *partialframe)
    609 {
    610     if ((start_code == MPEG4_start_code ||
    611                 start_code == MPEG2_start_code) &&
    612             partialframe) {
    613 
    614         *partialframe = 1;
    615 
    616         if (!skip_frame_boundary)
    617             *partialframe = 0;
    618 
    619         skip_frame_boundary = false;
    620     }
    621 }
    622 
    623 void frame_parse::update_skip_frame()
    624 {
    625     if (((start_code == MPEG4_start_code) &&
    626                 ((last_byte & 0xF0) == 0x20)) ||
    627             ((start_code == MPEG2_start_code) &&
    628              (last_byte == 0xB3))) {
    629 
    630         skip_frame_boundary = true;
    631     }
    632 }
    633